3

我一直在尝试使用tapply, ave,ddply按一组变量(年龄、性别)创建统计数据。我无法成功使用上述 R 命令。

library("ff")
df <- as.ffdf(data.frame(a=c(1,1,1:3,1:5), b=c(10:1), c=(1:10)))
tapply(df$a, df$b, length)

我得到的错误信息是

Error in as.vmode(value, vmode) : 
  argument "value" is missing, with no default

或者

Error in byMean(df$b, df$a) : object 'index' not found
4

1 回答 1

2

当前在包 ff 中实现的 ff_vectors 目前没有 tapply 或 ave。但是您可以做的是使用ffbase中的功能。让我们详细说明一些更大的数据集

require(ffbase)
a <- ffrep.int(ff(1:100000), times=500) ## 50Mio records on disk - not in RAM
b <- ffrandom(n=length(a), rfun = runif)
c <- ffseq_len(length(a))
df <- ffdf(a = a, b = b, c = c) ## on disk
dim(df)

对于您的简单聚合方法,您可以使用 binned_sum 轻松提取长度,如下所示。标记binned_sum在bin中需要一个ff因子对象,如图所示做as.character.ff即可。

df$groupbyfactor <- as.character(df$a)
agg <- binned_sum(x=df$b, bin=df$groupbyfactor, nbins = length(levels(df$groupbyfactor)))
head(agg)
agg[, "count"]

对于更复杂的聚合,您可以在 ffbase 中使用 ffdfdply。我经常做的是将它与一些 data.table 语句结合起来,如下所示:

require(data.table)
agg <- ffdfdply(df, split=df$groupbyfactor, FUN=function(x){
  x <- as.data.table(x)
  result <- x[, list(b.mean = mean(b), b.median = median(b), b.length = length(b),     whatever = b[c == max(c)][1]), by = list(a)]
  result <- as.data.frame(result)
  result
})
class(agg)
aggg <- as.data.frame(agg) ## Puts the data in RAM!

这会将您的数据以多组拆分元素的形式放在 RAM 中,您可以根据这些元素应用函数,例如一些 data.table 语句,这些语句要求您的数据位于 RAM 中。接下来,基于您应用该函数的所有块的结果将组合到一个新的 ffdf 中,以便您可以进一步使用它,或者如果您的 RAM 允许该大小,则将其放入 RAM 中。

块的大小由 getOption("ffbatchbytes") 控制。因此,如果您有更多的 RAM,那就更好了,因为它可以让您在 RAM 中的每个块中获取更多数据。

于 2013-05-10T08:10:55.550 回答