R语言 数据.表;更新筛选表/值的联接

0s7z1bwu  于 2023-03-10  发布在  其他
关注(0)|答案(2)|浏览(147)

我想使用带有table_b的更新连接来更新table_a的子集,但是在尝试更新连接之后,未过滤的table_a根本没有改变;

dat_a <- 
  data.table(postcode = LETTERS[1:10],
             values = c(1:8,NaN,10))
dat_b <- 
  data.table(postcode = LETTERS[1:10],
             values = c(990:999))

表A和表B的邮政编码相同,但值不同。table_a中有一个“NaN”值,我想用table_b中的相应值更新该值,但不想更新table_a中的所有其他值。

dat_a[is.nan(values)
      ][dat_b,
        values := i.values,
        on = .(postcode)]

根本不更改表

dat_a
    postcode values
 1:        A      1
 2:        B      2
 3:        C      3
 4:        D      4
 5:        E      5
 6:        F      6
 7:        G      7
 8:        H      8
 9:        I    NaN
10:        J     10

这个操作似乎已经成功了,所以我不确定为什么这个特定的值没有被引用更新。我需要做些什么不同的事情吗?

dat_a[is.nan(values)
      ][dat_b,
        values := i.values,
        on = .(postcode)][]

   postcode values
1:        I    998

注:另一种方法是过滤table_b中的值,但这对我的真实的数据集来说不是一个好的解决方案,因为我将不得不过滤table_b中的多个列以及该表中导致“NaN”结果的所有不同值,而不是仅过滤table_a中的“NaN”值的单个列。
例如,想象一下,如果不是只需要按邮政编码过滤,我必须按(postcode == "I" & age == 23 & qualification == "bachelors"过滤,然后对导致“NaN”结果的所有其他变量组合重复此操作)过滤

dat_a[dat_b[postcode == "I"],
      values := i.values,
      on = .(postcode)]

dat_a
    postcode values
 1:        A      1
 2:        B      2
 3:        C      3
 4:        D      4
 5:        E      5
 6:        F      6
 7:        G      7
 8:        H      8
 9:        I    998
10:        J     10
b09cbbtk

b09cbbtk1#

通过过滤,您可以创建另一个与原始表分离的深度复制表。您可以在此处使用fcoalesce代替过滤。它返回第一个非缺失值

dat_a[dat_b,
      # as numeric to ensure same variable type
      values := fcoalesce(values, as.numeric(i.values)), 
      on = .(postcode)]

dat_a
#>     postcode values
#>  1:        A      1
#>  2:        B      2
#>  3:        C      3
#>  4:        D      4
#>  5:        E      5
#>  6:        F      6
#>  7:        G      7
#>  8:        H      8
#>  9:        I    998
#> 10:        J     10
2j4z5cfb

2j4z5cfb2#

您还可以在每个数据集中设置一个辅助变量:

dat_a[, repl := is.nan(values)]
dat_b[, repl := TRUE]
dat_a[dat_b, on=.(postcode,repl), values := i.values]

#    postcode values   repl
#      <char>  <num> <lgcl>
# 1:        A      1  FALSE
# 2:        B      2  FALSE
# 3:        C      3  FALSE
# 4:        D      4  FALSE
# 5:        E      5  FALSE
# 6:        F      6  FALSE
# 7:        G      7  FALSE
# 8:        H      8  FALSE
# 9:        I    998   TRUE
#10:        J     10  FALSE

虽然有点笨拙,但这将允许您向数据集ab中的连接添加您所请求的各种需求。

dat_a[, repl := is.nan(values) & age == 23 & qualification == "bachelors"]

这在某种程度上类似于SQL中的where语句,其中不是指定一组标准来测试以针对每个可能返回的行查找TRUE/FALSE,而是在每个数据集中手动指定TRUE/FALSE,然后在该预定义的标准上进行内部联接。

相关问题