首页 > 解决方案 > 带有 `on = ` 的 data.table 子分配

问题描述

在进行子分配时,

RHS 长度必须为 1(单个值即可)或与 LHS 长度完全匹配,

正如错误消息所说,当不遵守规则时。

但是,以下工作:

tab.01 <- data.table( a = 1L:5L, b = 11L:15L )
tab.02 <- data.table( a = c(1L, 1L, 2L), x = c(11L, 12L, 22L) )

tab.01[ tab.02, x := i.x, on = "a"]
#    a  b  x
# 1: 1 11 12
# 2: 2 12 22
# 3: 3 13 NA
# 4: 4 14 NA
# 5: 5 15 NA

x列在功能上不依赖于a列。然而,进行了分配,如果我的猜测是正确的,则分配子组的最后一个元素。

可以更改此默认行为,例如选择第一个元素吗?以下试验不起作用:

  1. mult = "first"没有效果。
  2. tab.01[ tab.02, x := first(i.x), on = "a" ]将值 11L 分配给所有匹配项。
  3. tab.01[ tab.02, x := first(i.x), on = "a", by = "a"] 导致错误,因为i.x不再可用(或 中的任何其他列i)。
  4. tab.01[ tab.02, x := first(i.x), on = "a", by = .EACHI ]不会引发错误,但也不会修复任何东西。组中的值按行的顺序重新分配,因此保留最后一个值。

可以使用tab.02具有功能相关列的版本:

tab.02[ , y := f_fd(x), by = "a" ] # e.g. f_fd <- data.table::first
tab.01[ tab.02, x := y, on = "a"]

这是执行此任务的最简洁方式吗?

标签: rdata.table

解决方案


我相信没有专门用于实现此目的的内置方法。但是,可以在不修改tab.02.

你可以创建一个子集

tab.01[tab.02[rowid(a) == 1], x := i.x, on = "a"][]
#    a  b  x
# 1: 1 11 11
# 2: 2 12 22
# 3: 3 13 NA
# 4: 4 14 NA
# 5: 5 15 NA

或加入前订购

tab.01[tab.02[order(-x)], x := i.x, on = "a"][]
#    a  b  x
# 1: 1 11 11
# 2: 2 12 22
# 3: 3 13 NA
# 4: 4 14 NA
# 5: 5 15 NA

推荐阅读