【问题标题】:set operation within a list column在列表列中设置操作
【发布时间】:2016-12-12 07:32:00
【问题描述】:

我正在尝试在 this 等列表列中存储的向量之间进行 set 操作

DT  <- data.table(exp = c("exp1", "exp2", "exp2"), 
                  sample = c(1L, 1L, 2L), 
                  listdata = list(c(2L,5L), c(2L,3L,5L,7L), c(1L,2L,6L)))

> DT
    exp sample listdata
1: exp1      1      2,5
2: exp2      1  2,3,5,7
3: exp2      2    1,2,6

虽然很麻烦,但我可以做

DT$inc = list(setdiff(unlist(DT$listdata[2]), unlist(DT$listdata[1])))

并获取值为c(3,7) 的新列表列。但是如果我尝试使用

计算当前行和第一行之间的差异
DT$inc = list(list(setdiff(unlist(DT$listdata, recursive = FALSE), unlist(DT$listdata[1]))))

期待一个新列“inc”

0
c(3,7)
c(1,6)

我收到c(3,7,1,6)。显然unlist 将整个列表列展平在一起。知道发生了什么吗?

我也在学习 dplyr 和 data.table。因此,如果您可以使用其中之一提供解决方案,那将非常有帮助。

【问题讨论】:

    标签: r list data.table dplyr


    【解决方案1】:

    [...] 我尝试计算当前行和第一行之间的差异

    好吧,你可以这样做......

    DT[, inc := .(Map(setdiff, listdata, listdata[1L]))]
    
    #     exp sample listdata inc
    # 1: exp1      1      2,5    
    # 2: exp2      1  2,3,5,7 3,7
    # 3: exp2      2    1,2,6 1,6
    

    但我认为不使用列表列要好得多。


    不使用列表列可能看起来像...

    DT[, r := .I]
    DT2 = DT[,c(.SD[rep(.I, lengths(listdata))], .(v = unlist(listdata))), .SDcols=!"listdata"]
    
    #     exp sample r v
    # 1: exp1      1 1 2
    # 2: exp1      1 1 5
    # 3: exp2      1 2 2
    # 4: exp2      1 2 3
    # 5: exp2      1 2 5
    # 6: exp2      1 2 7
    # 7: exp2      2 3 1
    # 8: exp2      2 3 2
    # 9: exp2      2 3 6
    

    那我们就用这个数据集,就可以了

    DT2[!DT2[r==1L], on="v"]
    
    #     exp sample r v
    # 1: exp2      1 2 3
    # 2: exp2      1 2 7
    # 3: exp2      2 3 1
    # 4: exp2      2 3 6
    

    【讨论】:

    • 答案来得很快。你能解释一下listdata[1L]的用法吗?下面的dplyr版本需要使用[[。另外,当列表长度很长时,我不确定将列表分散到多行是否是个好主意。
    • @Dong 是的,我也注意到了这种差异。 listdata[[1]](在 Psidom 的回答中)是 lest 的第一个元素;而listdata[1] 是列表的slice,仅包含第一个元素。所以,如果Lst = list(11, 22),那么Lst[[1]]11Lst[1]list(11)1L 中的 L 仅使用 1 的整数版本。
    • 我需要一个他需要另一个的原因在于R的“回收”概念以及我们使用的两个函数的差异。如果您阅读有关回收和文档?lapply?Map 的内容,那么它应该是有意义的。如果没有,不妨试试聊天:chat.stackoverflow.com/rooms/25312/r-public
    • 哦,将它分散到多行的原因是因为 data.table 和 dplyr 都是这样构造的,以最有效地工作并使用最好的语法 - 通过将行分组在一起。跨度>
    • 不错的选择。加一。
    【解决方案2】:

    这里有一个对应的dplyr解决方案:

    library(dplyr)
    DT %>% mutate(inc = lapply(listdata, setdiff, listdata[[1]]))
    
    #   exp sample   listdata  inc
    #1 exp1      1       2, 5     
    #2 exp2      1 2, 3, 5, 7 3, 7
    #3 exp2      2    1, 2, 6 1, 6
    

    【讨论】:

      猜你喜欢
      • 2018-12-02
      • 1970-01-01
      • 2020-01-21
      • 2013-10-23
      • 1970-01-01
      • 2017-06-30
      • 1970-01-01
      • 2019-09-24
      • 2021-04-01
      相关资源
      最近更新 更多