我有两个要合并的数据框,如下所示:
df1 <- data.table(
color = c("Green", "Green", "Red","Red"),
year = c(1995, 2001,2010,1997)
)
df2 <- data.table(
color = c("Green", "Green", "Red", "Blue"),
value = 1:4,
year = c(1996, 2002, 2001, 2003)
)
我想合并这些,以便保留 df1 中的所有观测值,但它们仅与颜色组内具有最接近年份值的 df2 中的观测值配对。 我最好使用
tidyverse
来实现此目的。
我试过这个:
df1 %>%
inner_join(df2, by = 'color', suffix = c('.1', '.2')) %>%
group_by(color) #%>%
filter(abs(year.1 - year.2) == min(abs(year.1 - year.2)))
但是,这让我只能对每种“颜色”进行一次观察,而不是 df1 中的所有观察结果。如何合并以便保留 df1 的所有观测值,并且仅按颜色和最接近的年份值进行合并?另外,是否可以将其指定为最近的一年之前/之后/其中之一?
结果应如下所示:
df3 <- data.table(
color = c("Green", "Green", "Red","Red"),
year = c(1995, 2001,2010,1997),
value = c(1,2,3,3)
)
对于“最近”的一年,我们可以这样做:
df1 %>%
left_join(df2, join_by(color)) %>%
arrange( year.x, abs(year.x - year.y)) %>%
slice(1, .by = c(color, year.x))
# color year.x value year.y
#1 Green 1995 1 1996
#2 Red 1997 3 2001
#3 Green 2001 2 2002
#4 Red 2010 3 2001
对于“最接近的之前/之后”,我们可以这样做:
df1 %>%
left_join(df2, join_by(color, closest(year >= year)))
# color year.x value year.y
#1 Green 1995 NA NA
#2 Green 2001 1 1996
#3 Red 2010 3 2001
#4 Red 1997 NA NA
df1 %>%
left_join(df2, join_by(color, closest(year <= year)))
# color year.x value year.y
#1 Green 1995 1 1996
#2 Green 2001 2 2002
#3 Red 2010 NA NA
#4 Red 1997 3 2001
这是一个
data.table
解决方案:
library(data.table)
df1[, value := df2[df1, value, on = c("color == color", "year == year"),
roll = "nearest"]][]
#> color year value
#> 1: Green 1995 1
#> 2: Green 2001 2
#> 3: Red 2010 3
#> 4: Red 1997 3
创建于 2023-12-15,使用 reprex v2.0.2