> 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
作为向量,我不想将c
添加到data.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)
答案 0 :(得分:4)
> with(x, ave(a, b, FUN=mean) )
[1] 5 6 5 6 5 6 5 6 5 6
只是让data.table专家知道,我知道这可能无法很好地扩展到数百万的记录数据集,我很感谢关于这个主题的其他帖子。我一直在使用data.table来对我的大型分析产生良好的影响。这只是因为我表达了对我发布的数据参数的简单和不修改的渴望。
答案 1 :(得分:3)
您可以菊花链式连接"["
运算符:
x[, c := mean(a), by=b][, c]
# [1] 5 6 5 6 5 6 5 6 5 6
"[.data.table"
的结果本身就是一个data.table,所以你可以在它之后添加另一个。
我刚注意到关于不想修改x的评论。请注意,您需要以某种方式回收向量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
答案 2 :(得分:2)
这是另一种不修改原始data.table
的方式,但是这是一个完全人为的和不必要的约束,即你已经有了最好的解决方案。
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
答案 3 :(得分:1)
对于此特定示例,by(x$a,x$b,mean)[as.character(x$b)]
应该有效。我不太了解直方图问题,所以我不知道这是否会概括你想要的方式。