r - 根据键在数据框中汇总值

标签 r idioms

我有一段聚合代码,可以很好地运行,但是对具有10e6行的数据帧运行速度有点慢。我在R方面没有那么丰富的经验,所以我为我值得的代码深表歉意!

我只想对一个公用 key 进行基本的汇总和值的总和...

例如从...

  key val
1   a   5
2   b   7
3   a   6

至...
  key val
1   a   11
2   b   7

我能管理的最好的是...
keys = unique(inp$key)
vals = sapply(keys, function(x) { sum(inp[inp$key==x,]$val) })
out = data.frame(key=keys, val=vals)

我有这种直觉,认为inp[inp$key==x,]不是最好的方法。我缺少明显的速度吗?我可以在Hadoop中做到这一点(因为10e6数据集实际上已经是2e9行数据集的汇总),但我正在尝试提高R。

干杯,

最佳答案

使用tapply的另一种选择:

dat <- data.frame(key = c('a', 'b', 'a'), val = c(5,7,6))

> with(dat, tapply(val, key, FUN = sum))
 a  b 
11  7

我的测试表明这是进行此特定运动最快的方法,显然您的里程可能会有所不同:
fn.tapply <- function(daters) with(daters, tapply(val, key, FUN = sum))
fn.aggregate <- function(daters) aggregate(val~key, sum, data = daters)
fn.ddply <- function(daters) ddply(daters, .(key), summarize, val = sum(val))


library(rbenchmark)

benchmark(fn.tapply(dat), fn.aggregate(dat), fn.ddply(dat)
          , columns = c("test", "elapsed", "relative")
          , order = "relative"
          , replications = 100
          )


               test elapsed  relative
1    fn.tapply(dat)    0.03  1.000000
2 fn.aggregate(dat)    0.20  6.666667
3     fn.ddply(dat)    0.30 10.000000

请注意,对于真正的苹果与前两个苹果相比,将tapply解决方案转换为data.frame可以将这种差异减少约40%。

如注释中所示,使用1M行数据集似乎确实会改变一些情况:
 dat2 <- data.frame(key = rep(letters[1:5], each = 200000), val = runif(1e6))
> benchmark(fn.tapply(dat2), fn.aggregate(dat2), fn.ddply(dat2)
+           , columns = c("test", "elapsed", "relative")
+           , order = "relative"
+           , replications = 100
+           )
               test elapsed relative
1   fn.tapply(dat2)  39.114 1.000000
3     fn.ddply(dat2)  62.178 1.589661
2 fn.aggregate(dat2) 157.463 4.025745

关于r - 根据键在数据框中汇总值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6812077/

相关文章:

r - 合并行 - 在 R 中对某些列求和而不对其他列求和

javascript - 如何用 Ruby 编写 IIFE?

c - const 双指针的惯用 C

r - ggplot 中的条隐藏负标签 : geom_bar

r - 无法在服务器中加载工作区,文件具有魔数(Magic Number) 'RDX3'

clojure - 写这个的最惯用的 Clojure 方式是什么?

haskell - 帮助编写 "the colist Monad"(习语介绍论文中的练习)

go - 记录 Golang 程序的惯用方式,由一个 main.go 文件组成

r - 如何使用 R 中的分解功能分解 JSON 文件中的数据集?

r - 使用 Windows 身份验证访问 R 中的共享点