【问题标题】:count by levels on multiple columns按多列的级别计数
【发布时间】:2017-10-11 08:36:46
【问题描述】:

这是扩展名here
数据如下:

ID   Type    Problem1    Value1     Problem2    Value2    Problem3    Value3
1    A       X           500        Y           1000      Z           400
2    A       X           600        Z           700       
3    B       Y           700        Z           100
4    B       W           200        V           200
5    C       Z           500        V           500       
6    C       X           1000       W           100       V           900

我想要的结果是:

Type    X     Y     Z     W     V
A       2     1     2     0     0  
B       0     1     1     1     1
C       1     0     1     1     2

我想统计每个组下的数量,我该怎么做?

# data
dt <- fread("
ID   Type    Problem1    Value1     Problem2    Value2    Problem3    Value3
1    A       X           500        Y           1000      Z           400
2    A       X           600        Z           700       
3    B       Y           700        Z           100
4    B       W           200        V           200
5    C       Z           500        V           500       
6    C       X           1000       W           100       V           900", fill = T)  

我试试这个:

dcast(melt(dt, measure = patterns("^Value", "^Problem"), 
        value.name = c("Value", "Problem"))[Problem != ""
      ][, Problem := factor(Problem, levels = c("X", "Y", "Z", "W", "V"))], 
       Type ~Problem, value.var = "Value", sum / mean, na.rm = TRUE)

但是,它出错了。

【问题讨论】:

    标签: r data.table data-manipulation


    【解决方案1】:

    我会以长格式存储它(类似于 OP 的尝试)...

    dt[Problem3 == "", Problem3 := NA]
    mDT = melt(dt, 
      id = c("ID", "Type"), 
      meas = patterns("Problem", "Value"), 
      variable.name = "Item",
      value.name = c("Problem", "Value"),
      na.rm = TRUE
    )
    
        ID Type Item Problem Value
     1:  1    A    1       X   500
     2:  2    A    1       X   600
     3:  3    B    1       Y   700
     4:  4    B    1       W   200
     5:  5    C    1       Z   500
     6:  6    C    1       X  1000
     7:  1    A    2       Y  1000
     8:  2    A    2       Z   700
     9:  3    B    2       Z   100
    10:  4    B    2       V   200
    11:  5    C    2       V   500
    12:  6    C    2       W   100
    13:  1    A    3       Z   400
    14:  6    C    3       V   900
    

    然后它只是投射到宽:

    dcast(mDT, Type ~ Problem, fun.agg = length)
    
       Type V W X Y Z
    1:    A 0 0 2 1 2
    2:    B 1 1 0 1 1
    3:    C 2 1 1 0 1
    

    如果您希望列按特定顺序排列或想要包含未观察到的Problem 级别,您可以使用一个因子(就像 OP 所做的那样):

    dcast(mDT, Type ~ factor(Problem, levels=c("X","Y","Z","W","V")), fun.agg = length)
    
    # or more permanently
    
    mDT[, Problem := factor(Problem, levels=c("X","Y","Z","W","V"))]
    dcast(mDT, Type ~ Problem, fun.agg = length)
    

    【讨论】:

    • 我收到了这个Using 'Problem' as value column. Use 'value.var' to override Error in make.unique(sapply(unlist(lvars), all.vars, max.names = 1L), : 'sep' must be a character string
    • @PeterChen 嗯,我不确定为什么会发生这种情况。是针对此示例还是其他示例?由于有人赞成您的评论,我认为这可能是 data.table-version 问题。我正在 1.10.4 上进行测试(这是上周之前 CRAN 上的最新版本)并看到它可以正常工作。
    【解决方案2】:

    您可以尝试dplyr 解决方案:

    library(tidyverse)
    dt %>% 
      select(Type, starts_with("Problem")) %>% 
      gather(key, value, -Type) %>% 
      group_by(Type) %>% 
      filter(!value=="") %>% 
      count(value) %>% 
      spread(value, n, fill = 0)
    # A tibble: 3 x 6
    # Groups:   Type [3]
       Type     V     W     X     Y     Z
    * <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
    1     A     0     0     2     1     2
    2     B     1     1     0     1     1
    3     C     2     1     1     0     1
    

    【讨论】:

      【解决方案3】:
      # data
      dt <- fread("
                  ID   Type    Problem1    Value1     Problem2    Value2    Problem3    Value3
                  1    A       X           500        Y           1000      Z           400
                  2    A       X           600        Z           700       
                  3    B       Y           700        Z           100
                  4    B       W           200        V           200
                  5    C       Z           500        V           500       
                  6    C       X           1000       W           100       V           900", fill = T) 
      
      dt <- dt[,c("Type", "Problem1", "Problem2", "Problem3")]
      dt <- melt(dt, id = "Type")
      cnt <- dt[,.(freq = .N), by = .(Type, value)]
      
      mat <- reshape(cnt, idvar = "Type", timevar = "value", direction = "wide")
      > mat
          Type freq.X freq.Y freq.W freq.Z freq.V freq.
      1:    A      2      1     NA      2     NA     1
      2:    B     NA      1      1      1      1     2
      3:    C      1     NA      1      1      2     1
      

      【讨论】:

        猜你喜欢
        • 2018-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-20
        • 1970-01-01
        • 2022-01-06
        • 2015-04-06
        • 1970-01-01
        相关资源
        最近更新 更多