R 精确日期的左连接值,如果缺少,则查找上一个值
我有两个数据集df1和df2,它们都有共同的列date和country,用于左键连接数据集,特别是来自df2的列price。如果没有精确的匹配日期和国家,则丢失的值将按国家填充上一行的值。到目前为止,这种方法效果很好 但是,如果没有与国家的第一次观察结果完全匹配,我会遇到问题,因为这样就不可能用前一行填充它。在这种情况下,NA(如第1行);2015-07-18应填写df2之前的值,其中包含2015-07-15的观察结果。重要的是,我要匹配准确日期或前一日期的最新已知值,而不是最近的日期,即2017-07-20 在最终表格中,2015-07-18英国的价格应为2.5,这是最后一个已知值 下面是当前表格和示例数据R 精确日期的左连接值,如果缺少,则查找上一个值,r,dplyr,left-join,R,Dplyr,Left Join,我有两个数据集df1和df2,它们都有共同的列date和country,用于左键连接数据集,特别是来自df2的列price。如果没有精确的匹配日期和国家,则丢失的值将按国家填充上一行的值。到目前为止,这种方法效果很好 但是,如果没有与国家的第一次观察结果完全匹配,我会遇到问题,因为这样就不可能用前一行填充它。在这种情况下,NA(如第1行);2015-07-18应填写df2之前的值,其中包含2015-07-15的观察结果。重要的是,我要匹配准确日期或前一日期的最新已知值,而不是最近的日期,即201
date country price
1 2015-07-18 UK NA
2 2015-07-20 UK 3.0
3 2015-07-21 UK 2.7
4 2015-07-22 UK 4.5
5 2015-07-25 UK 4.6
6 2015-07-19 US 1.3
7 2015-07-20 US 2.7
8 2015-07-21 US 3.9
9 2015-07-22 US 2.8
10 2015-07-24 US 2.5
你可以尝试完全加入
Tho Vu击败了我,但我的解决方案非常相似:
full_join(df1,df2) %>%
arrange(country, date) %>%
mutate(price=ifelse(is.na(price), lag(price), price))
下面是一个在data.table中使用滚动联接的选项,该选项较短且应该快得多:
library(data.table)
setDT(df1)
setDT(df2)
df1[, price := df2[.SD, on=.(country, date), roll=Inf, price]]
输出:
date country price
1: 2015-07-18 UK 2.5
2: 2015-07-20 UK 3.0
3: 2015-07-21 UK 2.7
4: 2015-07-22 UK 4.5
5: 2015-07-25 UK 4.6
6: 2015-07-19 US 1.3
7: 2015-07-20 US 2.7
8: 2015-07-21 US 3.9
9: 2015-07-22 US 2.8
10: 2015-07-24 US 2.5
数据:
编辑:查找多个列:
cols <- c("price", "cost", "revenue")
df1[, (cols) := df2[.SD, on=.(country, date), roll=Inf, mget(cols)]]
我可能会先尝试完全连接,而不是左连接,然后在填充之后,在最后进行df1的右连接…感谢您的回复,这让我非常接近我想要的位置。这里唯一的小错误是df现在有11行,但每个国家应该只有10行5行。错误来自第5行,因为在2015-07-24 UK上应该没有条目,因为df1中也没有条目。未将其过滤掉,因为美国有2015-07-24这一日期的条目。有什么建议吗?太棒了,这正是我想要的。也许还有一点,如果我有几个专栏而不是价格,你能推荐一种方法吗。有什么快速的方法吗?如果对你有帮助的话,我很高兴。在这一点上,我认为如果您有多个列,我们可以使用相同的方法。然而,我担心还有其他更好的解决方法。这似乎是一个非常简短和快速的解决方案。如果df2中有多个列,它也可以工作吗?让我们假设还有成本和收入两列?有没有一种方法可以指定所有列?是的,你可以使用mget来获取这些列。在这种情况下,对于mget的具体使用有何建议?谢谢谢谢,正如预期的那样,代码非常简单。@edmond,你不必更改标记的答案,因为你的OP中有dplyr标记。你可以选择你选择的上一个答案。
date country price
1: 2015-07-18 UK 2.5
2: 2015-07-20 UK 3.0
3: 2015-07-21 UK 2.7
4: 2015-07-22 UK 4.5
5: 2015-07-25 UK 4.6
6: 2015-07-19 US 1.3
7: 2015-07-20 US 2.7
8: 2015-07-21 US 3.9
9: 2015-07-22 US 2.8
10: 2015-07-24 US 2.5
date <- as.Date(c("2015-07-18", "2015-07-20", "2015-07-21", "2015-07-22", "2015-07-25", "2015-07-19", "2015-07-20",
"2015-07-21", "2015-07-22", "2015-07-24"))
country <- c("UK", "UK", "UK", "UK", "UK", "US", "US", "US", "US", "US")
df1 <- data.frame(date, country)
date <- as.Date(c("2015-07-15", "2015-07-20", "2015-07-21", "2015-07-22", "2015-07-24", "2015-07-19", "2015-07-20",
"2015-07-21", "2015-07-22", "2015-07-24"))
country <- c("UK", "UK", "UK", "UK", "UK", "US", "US", "US", "US", "US")
price <- c(2.5, 3.0, 2.7, 4.5, 4.6, 1.3, 2.7, 3.9, 2.8, 2.5)
df2 <- data.frame(date, country, price)
cols <- c("price", "cost", "revenue")
df1[, (cols) := df2[.SD, on=.(country, date), roll=Inf, mget(cols)]]