【问题标题】:data.table conditional join overwrites columns used for condition- R [duplicate]data.table 条件连接覆盖用于条件 R 的列 [重复]
【发布时间】:2020-09-16 17:36:18
【问题描述】:

我正在尝试有条件地连接两个 data.tables df1 和 df2,但我得到了一个我无法解释的奇怪输出。

> df1 <- data.table(ID = 1, row_unique_identifier = 1:41, date_1 = as.Date(c(rep('2016-11-14',7), '2017-11-02', rep('2017-11-17',7), rep('2018-12-06', 20), rep('2018-12-07', 6))))
> df2=data.table(ID=1, Date_2A=as.Date(c('2016-11-14', '2018-12-06', '2017-11-17')), Date_2B = as.Date(c('2016-11-14', '2018-12-07', '2017-11-17')), Date_2B_EXTENDED = as.Date(c('2016-11-20', '2018-12-13', '2017-11-23')) )


> df2
   ID    Date_2A    Date_2B Date_2B_EXTENDED
1:  1 2016-11-14 2016-11-14       2016-11-20
2:  1 2018-12-06 2018-12-07       2018-12-13
3:  1 2017-11-17 2017-11-17       2017-11-23

我想有条件地加入 df1 和 df2 以便:

  1. 应返回所有 df1 行(因此它是左连接)
  2. df1.ID= df2.ID(df1 和 df2 是样本,实际上有很多ID)
  3. AND df1.date_1 介于 df2.Date_2A 和 df2.Date_2B_EXTENDED 之间
  4. 我希望我的输出包含所有 df1 列以及 df2 列,其中包含无法匹配的条目的 NA。

但是当我按如下方式进行连接时,输出很奇怪。似乎 Date_1 覆盖了 df2 的其他三列以及一些奇怪的 NA,它们也不在下面:

> df1[, c('Date_2A', 'Date_2B', 'Date_2B_EXTENDED') := df2[df1, on= .(ID
                                                                    , Date_2A <= date_1
                                                                    , Date_2B_EXTENDED >= date_1) 
                                                               ,.(Date_2A, Date_2B, Date_2B_EXTENDED)
                                                               , mult = "last"]]
> df1
    ID row_unique_identifier     date_1    Date_2A    Date_2B Date_2B_EXTENDED
 1:  1                     1 2016-11-14 2016-11-14 2016-11-14       2016-11-14
 2:  1                     2 2016-11-14 2016-11-14 2016-11-14       2016-11-14
 3:  1                     3 2016-11-14 2016-11-14 2016-11-14       2016-11-14
 4:  1                     4 2016-11-14 2016-11-14 2016-11-14       2016-11-14
 5:  1                     5 2016-11-14 2016-11-14 2016-11-14       2016-11-14
 6:  1                     6 2016-11-14 2016-11-14 2016-11-14       2016-11-14
 7:  1                     7 2016-11-14 2016-11-14 2016-11-14       2016-11-14
 8:  1                     8 2017-11-02 2017-11-02       <NA>       2017-11-02
 9:  1                     9 2017-11-17 2017-11-17 2017-11-17       2017-11-17
10:  1                    10 2017-11-17 2017-11-17 2017-11-17       2017-11-17
11:  1                    11 2017-11-17 2017-11-17 2017-11-17       2017-11-17
12:  1                    12 2017-11-17 2017-11-17 2017-11-17       2017-11-17
13:  1                    13 2017-11-17 2017-11-17 2017-11-17       2017-11-17
14:  1                    14 2017-11-17 2017-11-17 2017-11-17       2017-11-17
15:  1                    15 2017-11-17 2017-11-17 2017-11-17       2017-11-17
16:  1                    16 2018-12-06 2018-12-06 2018-12-07       2018-12-06
17:  1                    17 2018-12-06 2018-12-06 2018-12-07       2018-12-06
18:  1                    18 2018-12-06 2018-12-06 2018-12-07       2018-12-06
19:  1                    19 2018-12-06 2018-12-06 2018-12-07       2018-12-06
20:  1                    20 2018-12-06 2018-12-06 2018-12-07       2018-12-06
21:  1                    21 2018-12-06 2018-12-06 2018-12-07       2018-12-06
22:  1                    22 2018-12-06 2018-12-06 2018-12-07       2018-12-06
23:  1                    23 2018-12-06 2018-12-06 2018-12-07       2018-12-06
24:  1                    24 2018-12-06 2018-12-06 2018-12-07       2018-12-06
25:  1                    25 2018-12-06 2018-12-06 2018-12-07       2018-12-06
26:  1                    26 2018-12-06 2018-12-06 2018-12-07       2018-12-06
27:  1                    27 2018-12-06 2018-12-06 2018-12-07       2018-12-06
28:  1                    28 2018-12-06 2018-12-06 2018-12-07       2018-12-06
29:  1                    29 2018-12-06 2018-12-06 2018-12-07       2018-12-06
30:  1                    30 2018-12-06 2018-12-06 2018-12-07       2018-12-06
31:  1                    31 2018-12-06 2018-12-06 2018-12-07       2018-12-06
32:  1                    32 2018-12-06 2018-12-06 2018-12-07       2018-12-06
33:  1                    33 2018-12-06 2018-12-06 2018-12-07       2018-12-06
34:  1                    34 2018-12-06 2018-12-06 2018-12-07       2018-12-06
35:  1                    35 2018-12-06 2018-12-06 2018-12-07       2018-12-06
36:  1                    36 2018-12-07 2018-12-07 2018-12-07       2018-12-07
37:  1                    37 2018-12-07 2018-12-07 2018-12-07       2018-12-07
38:  1                    38 2018-12-07 2018-12-07 2018-12-07       2018-12-07
39:  1                    39 2018-12-07 2018-12-07 2018-12-07       2018-12-07
40:  1                    40 2018-12-07 2018-12-07 2018-12-07       2018-12-07
41:  1                    41 2018-12-07 2018-12-07 2018-12-07       2018-12-07

我理解输出的方式是,比较成功但 date_1 覆盖了与之比较的两列:Date_2A 和 Date_2B_EXTENDED。 Date_2B 中的 NA 条目有意义 --> 没有匹配项....但 date_1 仍然覆盖了该行的 date_2A 和 date_2B_EXTENDED。如何防止覆盖?我以前从来没有遇到过这种情况。我明确指定在匹配后向 df1 添加新列名,这是怎么回事?


编辑: 我通过添加两个额外的列找到了解决此问题的方法:Date_2A_dummy 和 Date_2B_EXTENDED_dummy 到 df2,它们分别与 Date_2A 和 Date_2B_EXTENDED 相同。然后将我的比较语句更改为这两个虚拟变量,它可以工作。但我仍然想知道这是否是最好的方法?!对我来说,这两个变量被覆盖的问题似乎是一个错误?我想不出任何用例来覆盖它们。

【问题讨论】:

  • 所以,我找到了解决此问题的方法,方法是向 df2 添加两个额外的 Date_2A_dummy 和 Date_2B_EXTENDED_dummy 列,它们分别与 Date_2A 和 Date_2B_EXTENDED 相同。然后将我的比较更改为这两个虚拟变量,就可以了。但是,我仍然想知道这是否是最好的方法?!在我看来,这两个变量被覆盖是一个错误

标签: r join data.table conditional-statements


【解决方案1】:

我想这就是你需要的......

df1[ df2, 
     `:=`( Date_2A = i.Date_2A, Date_2B = i.Date_2B, Date_2B_EXTENDED = i.Date_2B_EXTENDED ), 
     on = .( ID, date_1 >= Date_2A, date_1 <= Date_2B_EXTENDED ) ][]

输出

#     ID row_unique_identifier     date_1    Date_2A    Date_2B Date_2B_EXTENDED
#  1:  1                     1 2016-11-14 2016-11-14 2016-11-14       2016-11-20
#  2:  1                     2 2016-11-14 2016-11-14 2016-11-14       2016-11-20
#  3:  1                     3 2016-11-14 2016-11-14 2016-11-14       2016-11-20
#  4:  1                     4 2016-11-14 2016-11-14 2016-11-14       2016-11-20
#  5:  1                     5 2016-11-14 2016-11-14 2016-11-14       2016-11-20
#  6:  1                     6 2016-11-14 2016-11-14 2016-11-14       2016-11-20
#  7:  1                     7 2016-11-14 2016-11-14 2016-11-14       2016-11-20
#  8:  1                     8 2017-11-02       <NA>       <NA>             <NA>
#  9:  1                     9 2017-11-17 2017-11-17 2017-11-17       2017-11-23
# 10:  1                    10 2017-11-17 2017-11-17 2017-11-17       2017-11-23
# 11:  1                    11 2017-11-17 2017-11-17 2017-11-17       2017-11-23
# 12:  1                    12 2017-11-17 2017-11-17 2017-11-17       2017-11-23
# 13:  1                    13 2017-11-17 2017-11-17 2017-11-17       2017-11-23
# 14:  1                    14 2017-11-17 2017-11-17 2017-11-17       2017-11-23
# 15:  1                    15 2017-11-17 2017-11-17 2017-11-17       2017-11-23
# 16:  1                    16 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 17:  1                    17 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 18:  1                    18 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 19:  1                    19 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 20:  1                    20 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 21:  1                    21 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 22:  1                    22 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 23:  1                    23 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 24:  1                    24 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 25:  1                    25 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 26:  1                    26 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 27:  1                    27 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 28:  1                    28 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 29:  1                    29 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 30:  1                    30 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 31:  1                    31 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 32:  1                    32 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 33:  1                    33 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 34:  1                    34 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 35:  1                    35 2018-12-06 2018-12-06 2018-12-07       2018-12-13
# 36:  1                    36 2018-12-07 2018-12-06 2018-12-07       2018-12-13
# 37:  1                    37 2018-12-07 2018-12-06 2018-12-07       2018-12-13
# 38:  1                    38 2018-12-07 2018-12-06 2018-12-07       2018-12-13
# 39:  1                    39 2018-12-07 2018-12-06 2018-12-07       2018-12-13
# 40:  1                    40 2018-12-07 2018-12-06 2018-12-07       2018-12-13
# 41:  1                    41 2018-12-07 2018-12-06 2018-12-07       2018-12-13
#     ID row_unique_identifier     date_1    Date_2A    Date_2B Date_2B_EXTENDED

【讨论】:

  • 非常感谢。能否解释一下这段代码是如何工作的?我希望将 df1 外连接,而您的解决方案似乎是外连接 df2。我以前从未与:= 合作过(在''''中),[] 最后做了什么? <:>
  • 最后的[] 输出结果...可以省略。该联接是 df1 的更新联接,具有来自 df2 的数据。所以 df1 保持不变,并返回 on-statement 中的第一个匹配项。即使有多个匹配项,也只返回第一个匹配项。
猜你喜欢
  • 2015-04-29
  • 2016-11-12
  • 2017-07-01
  • 2013-10-03
  • 1970-01-01
  • 2014-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多