继我的问题之后: 1. Identifying whether a set of variables uniquely identifies each row of the data or not; 2. Tagging all rows that are duplicates in terms of a given set of variables, 我现在想通过获取它们的总和,根据给
1. Identifying whether a set of variables uniquely identifies each row of the data or not;
2. Tagging all rows that are duplicates in terms of a given set of variables,
我现在想通过获取它们的总和,根据给定的变量集合来聚合/合并所有重复的行.
解决方案1:
关于如何执行此操作有一些指导here,但是当存在构成索引的大量变量级别时,推荐的ddply方法很慢,因为在我试图标记所有的变量时由给定的变量集重复.
# Values of (f1, f2, f3, f4) uniquely identify observations dfUnique = expand.grid(f1 = factor(1:16), f2 = factor(1:41), f3 = factor(1:2), f4 = factor(1:104)) # sample some extra rows and rbind them dfDup = rbind(dfUnique, dfUnique[sample(1:nrow(dfUnique), 100), ]) # dummy data dfDup$data = rnorm(nrow(dfDup)) # aggregate the duplicate rows by taking the sum dfDupAgg = ddply(dfDup, .(f1, f2, f3, f4), summarise, data = sum(data))
解决方案2:
第二个解决方案是使用data.table,并按照建议here,我可以做到
# data.table solution indexVars = paste0('f', 1:4, sep = '') dtDup = data.table(dfDup, key = indexVars) dtDupAgg = dtDup[, list(data = sum(data)), by = key(dtDup)]
我有一些问题:
1.有没有办法让ddply版本更快?
2. data.table是否正确?我想检查,因为我是data.table的新手.
indexVars = paste0('f', 1:4, sep = '') dtDup <- as.data.table(dfDup) ## faster than data.table(.) dtDupAgg = dtDup[, list(data = sum(data)), by = c(indexVars)]
data.table版本1.9.2还实现了一个函数setDT,它允许通过引用将data.frames转换为data.tables(这意味着没有副本,因此转换几乎没有时间,特别是对大型data.frames有用) ).
所以,而不是做:
dtDup <- as.data.table(dfDup) dtDup[...]
你可以这样做:
## data.table v1.9.2+ setDT(dfDup) ## faster than as.data.table(.) dfDup[...] ## dfDup is now a data.table, converted by reference
在你的第一个问题上,plyr并不知道它的速度.查看Why is plyr so slow?(以及那里的许多信息性评论)以获取更多信息.
也许你可能对dplyr感兴趣,它比plyr快几个数量级,但仍然比data.table,恕我直言慢.这是等效的dplyr版本:
dfDup %.% group_by(f1, f2, f3, f4) %.% summarise(data = sum(data))
这是数据上data.table和dplyr之间的基准(所有时间都是连续三次运行的最小值):
## data.table v1.9.2+ system.time(ans1 <- dtDup[, list(data=sum(data)), by=c(indexVars)]) # user system elapsed # 0.049 0.009 0.057 ## dplyr (commit ~1360 from github) system.time(ans2 <- dfDup %.% group_by(f1, f2, f3, f4) %.% summarise(data = sum(data))) # user system elapsed # 0.374 0.013 0.389
我真的没有耐心去运行plyr版本(在第一次运行93秒后停止).正如你所看到的,dplyr比plyr快得多,但比data.table慢约7倍.
检查结果是否相等以确定:
all.equal(as.data.frame(ans1[order(f1,f2,f3,f4)]), as.data.frame(ans2)) # [1] TRUE
HTH