【问题标题】:Split a column list into columns将列列表拆分为列
【发布时间】:2021-02-12 18:47:30
【问题描述】:

假设我有一个 DT 为 -

id         values          valid_types   
 1            2|3             100|200  
 2              4                 200  
 3            2|1             500|100


valid_types 告诉我我需要哪些有效类型。共有 4 种类型(100、200、500、2000)。条目用|分隔的字符值指定它们的有效类型和对应的值。

我想将其转换为具有列类型及其对应值的 DT。

预期:

id   100   200  500
 1     2     3   NA
 2    NA     4   NA
 3     1    NA    2  

我想我可以把这两列都放在| 上,这会给我两个列表。然后我会通过将键设置为类型列表的名称来组合它们,然后将最终列表转换为 DT。

但我想出的想法非常复杂,而且没有真正奏效。

有没有更好/更简单的方法来做到这一点?

【问题讨论】:

    标签: r list data.table


    【解决方案1】:

    这是另一个data.table 方法:

    dcast(
      DT[, lapply(.SD, function(x) strsplit(x, "\\|")[[1L]]), by = id], 
      id ~ valid_types, value.var = "values"
    )
    

    【讨论】:

    • 啊。我正在这样做,而你在我之前解决了它。谢谢。这就是我想要的
    • 如果我的密钥 ID 是 2 个列的组合怎么办 -> id,date。我可以更改 by cluase 但我如何为 id~valid_types 做同样的事情?
    • @leoOrion id + date ~ valid_types
    【解决方案2】:

    使用tidyr 库,您可以将separate_rowspivot_wider 一起使用:

    library(tidyr)
    
    df %>%
      separate_rows(values, valid_types, sep = '\\|', convert = TRUE) %>%
      pivot_wider(names_from = valid_types, values_from = values)
    
    #     id `100` `200` `500`
    #  <int> <int> <int> <int>
    #1     1     2     3    NA
    #2     2    NA     4    NA
    #3     3     1    NA     2
    

    data.table 的方式是:

    library(data.table)
    library(splitstackshape)
    
    setDT(df)
    dcast(cSplit(df, c('values', 'valid_types'), sep = '|', direction = 'long'), 
                     id~valid_types, value.var = 'values')
    

    【讨论】:

    • 没有tidyr 有没有办法做到这一点?
    • 谢谢。但我试图用最少的包来实现这一点。因此,尽管这也解决了它,但还是选择了另一个答案。
    猜你喜欢
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    • 2022-01-09
    相关资源
    最近更新 更多