当前位置 : 主页 > 手机开发 > 其它 >

通过获取总和来聚合重复的行

来源:互联网 收集:自由互联 发布时间:2021-06-22
继我的问题之后: 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的新手.

关于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

网友评论