首页 > 解决方案 > R:通过匹配日期将值从一个数据帧导入到另一个数据帧

问题描述

假设我有df1:

Start_Date    End_Date     Value
2001-01-01    2001-12-31   1
2002-01-01    2002-12-31   2
2003-01-01    2003-12-31   3
2004-01-01    2004-12-31   4
2005-01-01    2005-12-31   5 

& df2:

DateTime      Gain   People
2003-01-01    3      3
2003-05-09    5      4
2004-12-31    1      2
2005-01-31    -2     2
2005-08-13    9      7
2006-09-10    6      8
2007-10-03    7      5

我想做的是通过检查 df2 中的哪个 DateTime 位于 df1 中的 Start_Date 和 End_Date 之间,将值从 df1 导入 df2。如果日期不属于 df1 中的任何时期,则返回值 0。期望结果的视图:

DateTime      Gain   People   Value
2003-01-01    3      3        3
2003-05-09    5      4        3
2004-12-31    1      2        4
2005-01-31    -2     2        5
2005-08-13    9      7        5
2006-09-10    6      8        0
2007-10-03    7      5        0

请指教

标签: rdataframedatetimedplyrsubset

解决方案


潜在的挑战是加入不平等条件。这些在 sql 中很简单,但在 R 中不是,因为 dplyr 仅在相等时加入。是关于 SO 的主要答案的链接

我发现的最好方法是进行更一般的连接,然后过滤不等式。

df1 = df1 %>% mutate(join_id = 1)
df2 = df2 %>% mutate(join_id = 1)

output = left_join(df2, df1, by = 'join_id') %>%
  filter(Start_Date <= DateTime,
         DateTime <= End_Date) %>%
  select(DateTime, Gain, People, Value) %>%
  mutate(Value = ifelse(is.na(Value), 0, Value)

解释:

  • 由于您的数据框没有现有的 ID 列,我们首先创建一个。如果你想加入一些等式约束和一些不等式约束,这是不必要的。
  • 我们使用(更)更一般的连接,然后是不等式约束的过滤器。
  • ifelse(is.na(...用于替换缺失值。

在某些情况下,这种更通用的连接会产生性能问题。但是由于 R 默认使用惰性求值,如果您在连接后立即进行过滤,那么 R 应该将两个语句作为同一连接的一部分运行并避免任何性能问题。


推荐阅读