我已经使用R很长一段时间了,我有一个特定的小任务的工作代码。但我想知道是否有更快的解决方案。
问题很简单:我的数据框tbl
有两列ID
和NrBlocks
。 ID不是唯一的,可能会多次出现,但具有相同或不同的NrBlocks
。该表实际上有更多列,但这些细节在这里无关紧要。我想要的只是每个唯一NrBlocks
的{{1}}值的总和。
工作代码(在重命名之前,我希望我没有因为这里的简化而引入拼写错误):
ID
有关提高速度的建议吗?
答案 0 :(得分:1)
强制性data.table
解决方案 -
options(stringsAsFactors=FALSE)
library(data.table)
##
set.seed(1234)
dTbl <- data.table(
ID = sample(c(letters,LETTERS),100000,replace=TRUE),
NrBlocks = rnorm(100000),
key = "ID")
##
gTbl <- dTbl[
,
list(sumNrBlocks = sum(NrBlocks)),
by = list(ID)]
##
> head(gTbl)
ID sumNrBlocks
1: A 56.50234
2: B -13.61380
3: C 24.66750
4: D 65.18829
5: E 26.14085
6: F 41.64376
时间:
library(microbenchmark)
##
uniqueIDs <- unique(dTbl$ID)
f1 <- function(){
sapply(1:length(uniqueIDs),
FUN = function(x){
sum(dTbl[which(dTbl$ID == uniqueIDs[x]),]$NrBlocks)
}
)
}
##
f2 <- function(){
dTbl[
,
list(sumNrBlocks = sum(NrBlocks)),
by = list(ID)]
}
##
Res <- microbenchmark(
f1(),
f2(),
times=100L)
Res
> Res
Unit: milliseconds
expr min lq median uq max neval
f1() 139.054620 141.534227 144.213253 156.747569 193.278071 100
f2() 1.813652 1.911069 1.980874 2.140971 3.522545 100
多列:
dTbl2 <- copy(dTbl)
set.seed(1234)
dTbl2[,col3:=rexp(100000)]
dTbl2[,col4:=col3*2]
##
gTbl2 <- dTbl2[
,
lapply(.SD,sum),
by=list(ID)]
##
> head(gTbl2)
ID NrBlocks col3 col4
1: A 56.50234 1933.443 3866.886
2: B -13.61380 1904.282 3808.563
3: C 24.66750 1834.655 3669.310
4: D 65.18829 1884.364 3768.728
5: E 26.14085 1874.761 3749.523
6: F 41.64376 1977.219 3954.438
具有规范的多列
gTbl2.2 <- dTbl2[
,
lapply(.SD,sum),
by=list(ID),
.SDcols=c(2,4)]
##
> head(gTbl2.2)
ID NrBlocks col4
1: A 56.50234 3866.886
2: B -13.61380 3808.563
3: C 24.66750 3669.310
4: D 65.18829 3768.728
5: E 26.14085 3749.523
6: F 41.64376 3954.438
答案 1 :(得分:0)
如果您有500毫秒的空余时间,可以在一个简单的行中使用aggregate
执行此操作。
aggregate(NrBlocks ~ ID, dat, mean)
microbenchmark(aggregate(NrBlocks ~ ID, dat, mean))
# Unit: milliseconds
# expr min lq median uq max neval
# f() 655.218 655.6562 656.6428 661.6947 667.0888 100
其中dat
是从nrussell表创建的数据框。
dim(dat)
# [1] 10000 2