【问题标题】:conditional data.table match for subset of data.tabledata.table 子集的条件 data.table 匹配
【发布时间】:2019-02-26 08:05:47
【问题描述】:

本帖与上一帖相关:match rows of two data.tables to fill subset of a data.table

不确定如何将它们集成在一起。 我有一种情况,除了 DT1 的一列的 NA 之外,还应该申请更多条件来合并,但这不起作用。

> DT1 <- data.table(colA = c(1,1, 2,2,2,3,3), colB = c('A', NA, 'AA', 'B', NA, 'A', 'C'), timeA = c(2,4,3,4,6,1,4))
> DT1
   colA colB timeA
1:    1    A     2
2:    1 <NA>     4
3:    2   AA     3
4:    2    B     4
5:    2 <NA>     6
6:    3    A     1
7:    3    C     4
> DT2 <- data.table(colC = c(1,1,1,2,2,3), timeB1 = c(1,3,6, 2,4, 1), timeB2 = c(2,5,7,3,5,4), colD = c('Z', 'YY', 'AB', 'JJ', 'F', 'RR'))
> DT2
   colC timeB1 timeB2 colD
1:    1      1      2    Z
2:    1      3      5   YY
3:    1      6      7   AB
4:    2      2      3   JJ
5:    2      4      5    F
6:    3      1      4   RR

使用与上述相同的指南,我想将 DT2 的 ColD 合并到 DT1 的 colB,仅用于 DT1 中 colB 的 NA 值,并使用 DT1 中的 timeA 在 DT2 中的 timeB1 和 timeB2 之间的 colD 值.我尝试了以下方法,但没有发生合并:

 > output <- DT1[DT2, on = .(colA = colC), colB := ifelse(is.na(x.colB) & i.timeB1 <= x.timeA & x.timeA <= i.timeB2, i.colD, x.colB)]
> output
> output
   colA colB timeA
1:    1    A     2
2:    1 <NA>     4
3:    2   AA     3
4:    2    B     4
5:    2 <NA>     6
6:    3    A     1
7:    3    C     4

输出没有任何变化。 这是我想要的输出:

> desired_output
   colA colB timeA
1:    1    A     2
2:    1   YY     4   --> should find a match
3:    2   AA     3
4:    2    B     4
5:    2 <NA>     6   --> shouldn't find a match
6:    3    A     1
7:    3    C     4

为什么这不起作用? 我想只使用 data.table 操作而不使用其他包。

【问题讨论】:

    标签: r data.table conditional match


    【解决方案1】:

    DT1 中的 colB 的就地更新将按如下方式工作:

    DT1[is.na(colB), colB := DT2[DT1[is.na(colB)], 
                        on = .(colC = colA, timeB1 <= timeA, timeB2 >= timeA), colD]]
    print(DT1)
       colA colB timeA
    1:    1    A     2
    2:    1   YY     4
    3:    2   AA     3
    4:    2    B     4
    5:    2 <NA>     6
    6:    3    A     1
    7:    3    C     4
    

    这会索引colBNA 的值,并且在根据on= ... 中定义的条件连接后,将缺失值替换为colD 中找到的匹配值。

    【讨论】:

    • 非常感谢您的解决方案。 timeA 的条件不是与 timeB1 相同,而是 timeB1
    • 不错的答案。 DT2[DT1[is.na(colB)], ... 可能是 DT2[.SD, ...,我想。
    【解决方案2】:

    可能不是最正确的答案,但它可以完成工作。我不是 data.table 专家,所以我欢迎改进/建议。

    DT1[ is.na(colB), colB := DT1[ is.na(colB), ][ DT2, colB := i.colD, on = c( "colA == colC", "timeA >= timeB1", "timeA <= timeB2")]$colB]
    

    是做什么的:
    首先,为所有行设置子集 DT1,其中 is.na(colB) = TRUE
    然后,使用来自 DT2 上相同行子集的非等连接结果的 colB 向量更新这些行中 colB 的值

    好处是 DT1 是通过引用进行更改的,因此它在处理大数据时非常快且内存效率很高(我认为)。

       colA colB timeA
    1:    1    A     2
    2:    1   YY     4
    3:    2   AA     3
    4:    2    B     4
    5:    2 <NA>     6
    6:    3    A     1
    7:    3    C     4
    

    【讨论】:

    • 我看到您的解决方案中发生了什么,非常感谢!!我仍然不明白为什么我的解决方案不起作用......
    猜你喜欢
    • 2014-03-24
    • 2013-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多