【问题标题】:R: Merge "Between" using Base RR:使用 Base R 合并“Between”
【发布时间】:2022-01-08 16:18:49
【问题描述】:

假设我有以下表格(注意:日期出现在我的问题中):

table_1 = data.frame(id = c("123", "123", "125", "125"), 
date_1 = c("2010-01-31","2010-01-31", "2015-01-31", "2018-01-31" ))

table_1$id = as.factor(table_1$id)
table_1$date_1 = as.factor(table_1$date_1)

table_2 = data.frame(id = c("123", "121", "125", "126"), 
date_2 = c("2009-01-31","2010-01-31", "2010-01-31", "2010-01-31" ),
date_3 = c("2011-01-31","2010-01-31", "2020-01-31", "2020-01-31" ))


table_2$id = as.factor(table_2$id)
table_2$date_2 = as.factor(table_2$date_2)
table_2$date_3 = as.factor(table_2$date_3)

我想使用以下条件对这两个表执行(某种类型的)“连接”(现在没关系,例如右连接、内连接等):

1) 如果 table_1$id = table_2$id

2) 如果 table_1$date BETWEEN(table_2$date_2,table_2$date_3)

我在 Stackoverflow 上发现了一个先前的问题,该问题演示了如何使用“SQLDF”库来做到这一点:r merge by id and date between two dates

library(sqldf)

final = sqldf("select a.*, b.*
           
       from table_1 a left join table_2 b
       on a.id = b.id and 
          a.date_1 between 
              b.date_2 and
              b.date_3")
head(final)
#for some reason, this produces duplicate rows, I don't know why



id     date_1  id     date_2     date_3
1 123 2010-01-31 123 2009-01-31 2011-01-31
2 123 2010-01-31 123 2009-01-31 2011-01-31
3 125 2015-01-31 125 2010-01-31 2020-01-31
4 125 2018-01-31 125 2010-01-31 2020-01-31

#optional: remove duplicates
final_no_dup <- final[!duplicated(final$id),]

我的问题:有没有办法使用 Base R 执行上述“加入”?如果这在 Base R 中是不可能的,可以在“dplyr”中完成吗?

【问题讨论】:

  • 这些不是重复的。表 1 的前 2 行完全相同。
  • 您不需要写“我正在使用 R 编程语言”。这就是r 标签的用途。

标签: sql r join dplyr data-manipulation


【解决方案1】:

你可以在dplyr试试这个方法

table_1 %>%
      left_join(table_2, by = "id") %>%
      mutate(across(2:4, ~as.Date(.x))) %>%
      filter(date_1 <= max(date_3, date_2), date_1 >= min(date_2, date_3)) %>%
      distinct()
    
       id     date_1     date_2     date_3
    1 123 2010-01-31 2009-01-31 2011-01-31
    2 125 2015-01-31 2010-01-31 2020-01-31
    3 125 2018-01-31 2010-01-31 2020-01-31

基地R

table_3 <- merge(x = table_1, y = table_2, by = "id", all.x = TRUE)
table_3 <- table_3[table_3$date_1 <= max(table_3$date_2, table_3$date_3) && table_3$date_1 >= min(table_3$date_2,table_3$date_3)]
table_3[!duplicated(table_3),]

【讨论】:

  • @公园:非常感谢您的回答!你能告诉我为什么需要代码行“ mutate(across(2:4, ~as.Date(.x))) %>%”吗?谢谢!
  • @朴:谢谢你的回复!您认为在运行联接之前以某种方式更改“table_1”和“table_2”中所有日期变量的日期格式更好吗?
  • @Park : 我还是很好奇 Base R 中有没有办法做到这一点?
  • @stats555 如果这些日期是日期,最好不要将它们编码为一个因素。如果你不添加as.factor 部分,你也不需要mutate(across(2:4, ~as.Date(.x))) %&gt;% 行。而且我不确定Base R,我不擅长base R加入
猜你喜欢
  • 2023-01-02
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
  • 1970-01-01
  • 2019-02-04
  • 2021-08-10
  • 1970-01-01
  • 2016-02-06
相关资源
最近更新 更多