【问题标题】:count unique combinations of values计算值的唯一组合
【发布时间】:2012-02-10 08:05:43
【问题描述】:

我的数据框如下所示:

ID | value 1 | value 2 | value 3 | value 4
1  |    M    |    D    |    F    |   A
2  |    F    |    M    |    G    |   B
3  |    M    |    D    |    F    |   A
4  |    L    |    D    |    E    |   B

我想要这样的东西。

value 1 | value 2 | value 3 | value 4|  Number of combinations
  M     |    D    |    F    |   A    |     2
  F     |    M    |    G    |   B    |     1
  L     |    D    |    E    |   B    |     1

例如计算列值 1 - 值 4 的唯一组合数。

【问题讨论】:

    标签: r unique combinations


    【解决方案1】:

    plyr 包中的count 将完成该任务。

    > df
      ID   value.1   value.2   value.3 value.4
    1  1     M         D         F           A
    2  2     F         M         G           B
    3  3     M         D         F           A
    4  4     L         D         E           B
    > library(plyr)
    > count(df[, -1])
        value.1   value.2   value.3 value.4 freq
    1     F         M         G           B    1
    2     L         D         E           B    1
    3     M         D         F           A    2
    

    【讨论】:

      【解决方案2】:
      N <- 10000
      
      d <- data.frame(
        ID=seq(1, N), 
        v1=sample(c("M","F", "M", "L"), N, replace = TRUE), 
        v2=sample(c("D","M","D","D"), N, replace = TRUE), 
        v3=sample(c("F","G","F","E"), N, replace = TRUE),
        v4=sample(c("A","B","A","B"), N, replace = TRUE)
      )
      

      有data.table(最快)

      dt <- data.table::as.data.table(d)
      dt[, .N, by = c('v1','v2','v3','v4')]
      

      使用 dplyr

      dplyr::count_(d, vars = c('v1','v2','v3','v4'))
      

      使用 plyr

      plyr::count(d, vars = c('v1','v2','v3','v4'))
      plyr::ddply(d, .variables = c('v1','v2','v3','v4'), nrow)
      

      有聚合(最慢)

      aggregate(ID ~ ., d, FUN = length)
      

      基准测试

      microbenchmark::microbenchmark(dt[, .N, by = c('v1','v2','v3','v4')],
                                     plyr::count(d, vars = c('v1','v2','v3','v4')),
                                     plyr::ddply(d, .variables = c('v1','v2','v3','v4'), nrow),
                                     dplyr::count_(d, vars = c('v1','v2','v3','v4')),
                                     aggregate(ID ~ ., d, FUN = length), 
                                     times = 1000)
      
      Unit: microseconds
                                                               expr      min       lq      mean   median        uq        max neval  cld
                           dt[, .N, by = c("v1", "v2", "v3", "v4")]  887.807 1107.543  1263.777 1174.258  1289.724   4263.156  1000 a   
                   plyr::count(d, vars = c("v1", "v2", "v3", "v4")) 3912.791 4270.387  5379.080 4498.053  5791.743 157146.103  1000   c 
       plyr::ddply(d, .variables = c("v1", "v2", "v3", "v4"), nrow) 7737.874 8553.370 10630.849 9018.266 11126.517 187301.696  1000    d
                 dplyr::count_(d, vars = c("v1", "v2", "v3", "v4")) 2126.913 2432.957  2763.499 2568.251  2789.386  12549.669  1000  b  
                                 aggregate(ID ~ ., d, FUN = length) 7395.440 8121.828 10546.659 8776.371 10858.263 210139.759  1000    d
      

      似乎最好简单地使用data.table 而不是data.frame,因为它是最快的并且不需要其他函数或库来计算。另请注意,aggregate 函数在大型数据集上的执行速度要慢得多。

      最后一点:随时更新新方法。

      【讨论】:

      • 我认为您应该显示更大数据集的结果。另外,在查看args(plyr::count) 之后,我猜plyr::count(d, c('v1','v2','v3','v4')) 可能是正确的。可能还有一个dplyr::count 可以考虑。
      • @Frank,它现在基于 10k 行。
      • 好的,谢谢。另一点:length(ID) 现在似乎不会给出正确的结果,因为ID 重复值。测试方法间结果的相等性通常是一个好主意。哦,没关系,我想它有什么价值并不重要。 Fwiw,data.table 速度快的原因记录在?GForce
      • 它们给出了不同的格式,但 tapply(d$ID, d[, -1], length)table(d[, -1]) 在这种特殊情况下也很快。
      【解决方案3】:

      没有 plyr。

      aggregate(ID ~ ., d, FUN=length)# . means all variables in d except ID
      

      【讨论】:

      • 不错,但与 plyr::count 相比非常 (!!) 慢。从 microbenchmark 测试,4000x500 DF 总结 3 列的频率,似乎 count 快 20 倍(!)。
      【解决方案4】:

      这里是使用plyr 包的解决方案

      library(plyr)
      d <- data.frame(
          ID=seq(1,4), v1=c("M","F", "M", "L"), 
          v2=c("D","M","D","D"), v3=c("F","G","F","E"), v4=c("A","B","A","B")
      )
      ddply(d,.(v1,v2,v3,v4), nrow)
      

      我希望这不是家庭作业...

      【讨论】:

        猜你喜欢
        • 2019-06-18
        • 1970-01-01
        • 1970-01-01
        • 2014-04-16
        • 1970-01-01
        • 1970-01-01
        • 2011-06-09
        • 1970-01-01
        • 2018-04-01
        相关资源
        最近更新 更多