【问题标题】:Remove row-specific items from list从列表中删除特定于行的项目
【发布时间】:2015-07-02 21:18:40
【问题描述】:

我想从之前的 3 列('group'、'animal' 和 'full')中创建最后一列('desired_result')。以下是可重现示例的代码。

library(data.table)
data = data.table(group = c(1,1,1,2,2,2), animal = c('cat', 'dog', 'pig', 'giraffe', 'lion', 'tiger'), desired_result = c('dog, pig', 'cat, pig', 'cat, dog', 'lion, tiger', 'giraffe, tiger', 'giraffe, lion'))
data[, full := list(list(animal)), by = 'group']
data = data[, .(group, animal, full, desired_result)]

data
    group  animal               full   desired_result
1:     1     cat          cat,dog,pig     dog, pig
2:     1     dog          cat,dog,pig     cat, pig
3:     1     pig          cat,dog,pig     cat, dog
4:     2 giraffe   giraffe,lion,tiger    lion, tiger
5:     2    lion   giraffe,lion,tiger    giraffe, tiger
6:     2   tiger   giraffe,lion,tiger    giraffe, lion

基本上,我想修改“完整”,使其不包含相应的“动物”。我尝试了使用这些列的列表和字符版本的各种 lapply 命令,但未能解决这个问题。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    这是一种可能的方法

    data[, desired_result := {
            temp <- unique(unlist(full)) 
            toString(temp[-match(animal, temp)])
            }, by = .(group, animal)]
    data
    #    group  animal               full desired_result
    # 1:     1     cat        cat,dog,pig       dog, pig
    # 2:     1     dog        cat,dog,pig       cat, pig
    # 3:     1     pig        cat,dog,pig       cat, dog
    # 4:     2 giraffe giraffe,lion,tiger    lion, tiger
    # 5:     2    lion giraffe,lion,tiger giraffe, tiger
    # 6:     2   tiger giraffe,lion,tiger  giraffe, lion
    

    【讨论】:

      【解决方案2】:

      另一种选择:

      data[, desired := .(Map(setdiff, list(animal), as.list(animal))), by = group]
      
      #or if starting from full
      data[, desired := .(Map(setdiff, full, animal))]
      

      (回收魔法使第一个版本工作)

      【讨论】:

      • dplyr 中的相同想法:library(dplyr); data %&gt;% mutate(desired = Map(setdiff, full, animal))
      • 这将返回一个列表而不是字符向量(根据 OP 所需的输出)。
      • 我读了 OP,因为他们不在乎他们是否得到一个列表或一个字符串并且转换是微不足道的
      • 我应该提到我在列表或字符串之间并不挑剔。正如 eddi 所说,转换并不难。
      • 也许,我只是查看了他们提供的所需输出,这明确是一个字符向量。但看来你是对的
      【解决方案3】:

      我也找到了办法!

      通过将“动物”变成一个列表,我可以使用 mapply。

      data$animal = strsplit(data$animal, ' ')
      data$check = mapply(function(x, y) {list(x[x != y]) }, data$full, data$animal)
      
      data
      group  animal               full desired_result         check
      1:     1     cat        cat,dog,pig       dog, pig       dog,pig
      2:     1     dog        cat,dog,pig       cat, pig       cat,pig
      3:     1     pig        cat,dog,pig       cat, dog       cat,dog
      4:     2 giraffe giraffe,lion,tiger    lion, tiger    lion,tiger
      5:     2    lion giraffe,lion,tiger giraffe, tiger giraffe,tiger
      6:     2   tiger giraffe,lion,tiger  giraffe, lion  giraffe,lion
      

      【讨论】:

      • 您的方法将返回一个列表而不是字符向量(根据您想要的输出)
      • 嗯,好点,必要时必须进行转换和清理。
      猜你喜欢
      • 2016-01-29
      • 2022-01-08
      • 2019-03-17
      • 2018-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多