R计算df增加性能内的计数子集

时间:2015-07-23 05:50:19

标签: r performance

我目前正在使用看起来像这样的数据集

Host   V1   V2   V3   V4
H1     1    1    1    1
H1     1    1    1    0
H2     1    1    0    0
H2     1    0    0    0
H3     0    0    0    0
H3     1    1    1    1

顶行只是标题。最终目标是能够计算每列中每个类别的主机数量。这看起来像这样

Host   V1   V2   V3   V4
H1     2    2    2    1
H2     2    1    0    0
H3     1    1    1    1

目前我正在使用以下代码

ddply(data,.(data[,1]),numcolwise(sum))

这给了我正确的输出,这对于许多不同的生成数据集来说,直到我需要成千上万次运行此操作,这一直很好。通常,这需要数小时(如果不是几天),理想情况下这可以减少到几分钟。当我用Rprof分析我的整体代码时,它确定ddply函数占绝大多数时间。我想大大加快这个过程,但我不知道更有效的方法来缩小这些数据集。

2 个答案:

答案 0 :(得分:2)

data.table包似乎要快得多:

Arrgh!> library(data.table)
Arrgh!> read.table(t="Host   V1   V2   V3   V4
+ H1     1    1    1    1
+ H1     1    1    1    0
+ H2     1    1    0    0
+ H2     1    0    0    0
+ H3     1    1    1    1", h=T)->df
Arrgh!> dt<-data.table(df)
Arrgh!> dt[, lapply(.SD, sum), by = Host]
   Host V1 V2 V3 V4
1:   H1  2  2  2  1
2:   H2  2  1  0  0
3:   H3  1  1  1  1

例如:

Arrgh!> H <- c("H1","H2","H3")
Arrgh!> V <- c(0,1)
Arrgh!> df <- data.frame(Host=sample(H, 1000, r=T), V1=sample(V,1000,r=T), V2=sample(V,1000,r=T), V3=sample(V,1000,r=T), V4=sample(V,1000,r=T))
Arrgh!> dt <- data.table(df)
Arrgh!> library(microbenchmark)

Arrgh!> microbenchmark(dt[, lapply(.SD, sum), by = Host])
Unit: milliseconds
                              expr   min   lq  mean median    uq   max neval
 dt[, lapply(.SD, sum), by = Host] 1.515 1.56 1.655  1.581 1.627 4.288   100

Arrgh!> microbenchmark(ddply(df,.(df[,1]),numcolwise(sum)))
Unit: milliseconds
                                   expr   min    lq  mean median    uq   max neval
 ddply(df, .(df[, 1]), numcolwise(sum)) 4.097 4.173 4.458  4.236 4.343 9.958   100

答案 1 :(得分:1)

使用dplyr

  library(dplyr)
  df1 %>% 
    group_by(Host) %>% 
    summarise_each(funs(sum))
  #   Host V1 V2 V3 V4
  #1   H1  2  2  2  1
  #2   H2  2  1  0  0
  #3   H3  1  1  1  1

aggregate来自base R

 aggregate(.~Host, df1, FUN=sum)
 #   Host V1 V2 V3 V4
 #1   H1  2  2  2  1
 #2   H2  2  1  0  0
 #3   H3  1  1  1  1

或使用rowsum

rowsum(df1[-1], group = df1$Host)
#    V1 V2 V3 V4
#H1  2  2  2  1
#H2  2  1  0  0
#H3  1  1  1  1