5
> x <- data.table(a=1:10, b=rep(1:2, 5))
> x
     a b
 1:  1 1
 2:  2 2
 3:  3 1
 4:  4 2
 5:  5 1
 6:  6 2
 7:  7 1
 8:  8 2
 9:  9 1
10: 10 2
> x[,c:=mean(a), by=b]
> y <- x$c
> y
 [1] 5 6 5 6 5 6 5 6 5 6

最终,我对y作为向量感兴趣,我不想添加cdata.table. 有没有更简单的方法可以y从原版中获取x

当我尝试将不同的权重应用于直方图中的不同组时,就会出现问题。

# here weight would be the same for all colour, but I wish they differ.
geom_freqpoly(aes(colour=group, weight=mean(y)), binwidth=1)
4

4 回答 4

4
> with(x, ave(a, b, FUN=mean) )
 [1] 5 6 5 6 5 6 5 6 5 6

只是为了让 data.table 专家知道,我知道这可能无法很好地扩展到数百万条记录数据集,我很感激关于这个主题的其他帖子。我一直在使用 data.table 对我的大型分析产生良好的影响。只是因为表达了对我发布的数据论点的简单性和不修改的渴望。

于 2013-09-30T21:53:46.890 回答
3

您可以菊花链"["操作员:

x[, c := mean(a), by=b][, c]
# [1] 5 6 5 6 5 6 5 6 5 6

结果"[.data.table"本身就是一个data.table,所以你可以在它之后添加另一个。


我刚刚注意到关于不想修改 x 的评论。请注意,您需要以某种方式回收 vector c。R 通常会为您处理这个问题。如果要手动执行,请使用:

 x[, list(c=mean(a)), by=b][, rep(c, length(x$a)/length(c))]
 # [1] 5 6 5 6 5 6 5 6 5 6

至于不修改的动机x,请注意分配一列然后稍后将其删除的开销几乎可以忽略不计,x[, c := NULL] 因此也许暂时修改 DT 是要走的路。


根据@Frank 的要求,这里有一个简单的基准:有 100 个元素,by速度更快。但是速度下降很快

# The call used for benchmarking is as follows: 
library(microbenchmark)
microbenchmark(B = as.vector(by(x$a,x$b,mean)[as.character(x$b)]), 
               D = x[, list(c=mean(a)), by=b][, rep(c, length(x$a)/length(c))]
               )



# medium sized x
N <- 1e4
x <- {set.seed(1); data.table(a=1:(N), b=sample(5, N, TRUE), key="b")}

Unit: milliseconds
 expr      min       lq   median       uq       max neval
    B 6.150740 6.284466 6.403332 7.790877 10.339314   100
    D 1.268631 1.337959 1.441184 1.525279  2.963625   100
于 2013-09-30T15:12:34.077 回答
2

这是另一种在不修改原始文件的情况下执行此操作的方法data.table,但 imo 这完全是人为且不必要的约束,即您已经拥有最佳解决方案。

x[, list(.I, mean(a)), by = b][order(.I), V2]
#[1] 5 6 5 6 5 6 5 6 5 6

# or for faster ordering
setkey(x[, list(.I, mean(a)), by = b], .I)$V2
于 2013-09-30T17:38:20.863 回答
1

对于这个特定的例子,by(x$a,x$b,mean)[as.character(x$b)]应该工作。我不太了解直方图问题,所以我不知道这是否会概括您想要的方式。

于 2013-09-30T14:46:45.737 回答