条件 data.table 匹配 data.table 的子集
conditional data.table match for subset of data.table
这个post与之前的post相关:
不确定如何将它们整合在一起。
我有一种情况,除了 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 值,并使用 colD 的值,其中 DT1 中的 timeA 在 timeB1 和 timeB2 之间在 DT2 中。我尝试了以下但合并没有发生:
> 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 操作而不使用额外的包。
可能不是最好的答案,但它完成了工作。我不是 data.table 专家,所以我欢迎 improvements/suggestions。
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
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
这会为 colB
为 NA
的值编制索引,并根据 on= ...
中定义的条件进行联接后,用 [=] 中找到的匹配值替换缺失值16=].
这个post与之前的post相关:
不确定如何将它们整合在一起。 我有一种情况,除了 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 值,并使用 colD 的值,其中 DT1 中的 timeA 在 timeB1 和 timeB2 之间在 DT2 中。我尝试了以下但合并没有发生:
> 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 操作而不使用额外的包。
可能不是最好的答案,但它完成了工作。我不是 data.table 专家,所以我欢迎 improvements/suggestions。
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
好处是 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
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
这会为 colB
为 NA
的值编制索引,并根据 on= ...
中定义的条件进行联接后,用 [=] 中找到的匹配值替换缺失值16=].