超级叠加直方图拟合在一个图中的ggplot。

3

我有大约5个非常大的向量(约1.08亿个条目),因此在R中进行任何绘图/操作都需要花费相当长的时间。

我正试图可视化它们的分布(直方图),不知道如何在R中最好地叠加它们的直方图分布,而不会导致太长时间的等待。我想首先将一个分布拟合到直方图中,然后在一个图中绘制所有的分布线拟合。

您对如何实现这一点有什么建议吗?

假设我的向量是:

x1, x2, x3, x4, x5.

我将尝试使用这段代码:在R中使用ggplot2叠加直方图 以下是我用于3个向量的示例代码(R无法绘制):
n = length(x1)
dat <- data.frame(xx = c(x1, x2, x3),yy = rep(letters[1:3],each = n))
ggplot(dat,aes(x=xx)) + 
    geom_histogram(data=subset(dat,yy == 'a'),fill = "red", alpha = 0.2) +
    geom_histogram(data=subset(dat,yy == 'b'),fill = "blue", alpha = 0.2) +
    geom_histogram(data=subset(dat,yy == 'c'),fill = "green", alpha = 0.2)

但是生成图表需要很长时间,最终会将我踢出R。有没有关于如何高效使用ggplot2处理大向量的建议?在我的情况下,似乎需要创建一个包含5*108MM条目的数据框才能进行绘图,这非常低效。

谢谢!

1个回答

20

以下是 Rcpp 的一小段代码,可以非常高效地对数据进行分组 - 在我的电脑上,将 1 亿个观测值分组大约只需要一秒钟:

library(Rcpp)
cppFunction('
  std::vector<int> bin3(NumericVector x, double width, double origin = 0) {
    int bin, nmissing = 0;
    std::vector<int> out;

    NumericVector::iterator x_it = x.begin(), x_end;
    for(; x_it != x.end(); ++x_it) {
      double val = *x_it;
      if (ISNAN(val)) {
        ++nmissing;
      } else {
        bin = (val - origin) / width;
        if (bin < 0) continue;

        // Make sure there\'s enough space
        if (bin >= out.size()) {
          out.resize(bin + 1);
        }
        ++out[bin];
      }
    }

    // Put missing values in the last position
    out.push_back(nmissing);
    return out;
  }
')

x8 <- runif(1e8)
system.time(bin3(x8, 1/100))
#   user  system elapsed 
#  1.373   0.000   1.373 

话虽如此,hist在这里也相当快:

system.time(hist(x8, breaks = 100, plot = F))
#   user  system elapsed 
#  7.281   1.362   8.669 

使用bin3绘制直方图或频率多边形很简单:

# First we create some sample data, and bin each column

library(reshape2)
library(ggplot2)

df <- as.data.frame(replicate(5, runif(1e6)))
bins <- vapply(df, bin3, 1/100, FUN.VALUE = integer(100 + 1))

# Next we match up the bins with the breaks
binsdf <- data.frame(
  breaks = c(seq(0, 1, length = 100), NA),
  bins)

# Then melt and plot
binsm <- subset(melt(binsdf, id = "breaks"), !is.na(breaks))
qplot(breaks, value, data = binsm, geom = "line", colour = variable)

顺便提一下,我手头有bin3的原因是我正在研究如何使这种速度成为ggplot2中的默认设置 :)


谢谢,看起来非常快速和漂亮;-) 喜欢Rcpp,之前不太熟悉它。 - Dnaiel
@hadley 有一个小错误,你需要使用双引号来修正代码。 - agstudy
@dwin @agstudy 哦 - 这就是为什么我通常坚持使用单独的C++文件和sourceCpp的原因。 - hadley
哦,有人能为我解释一下这个错误吗:“在 sourceCpp(code = code,env = env,rebuild = rebuild,showOutput = showOutput,:Error 1 occurred building shared library.” - Rico
谢谢@hadley - 因为我之前没有听说过这些工具,所以这一定是它。 - Rico
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接