假设我有两个数据帧,如下所示:
df1 <- data.frame(
X = c(1,2,2),
Y = c("a","b","c"),
Z = c(10,20,30)
)
df2 <- data.frame(
X = c(1,2,2,4),
Y = c(NA,"b","c","d"),
W = c(-1,-2,-3,-4)
)
我想在df2上同时使用X和Y加入df1。但对于第一个观察,我只使用X。最后,我想得到:
df3 <- data.frame(
X = c(1,2,2,4),
Y = c(NA,"b","c","d"),
W = c(-1,-2,-3,-4),
Z = c(10,20,30,NA)
)
无法使用left_join或full_join完成此操作。
发布于 2020-06-26 00:51:30
您可以通过两个步骤完成此操作。首先,使用X和Y在df1上使用左连接df2。其次,将Z中缺少的任何值替换为仅基于X的df1中的相应值。但只有在X中没有重复的情况下,这才能起作用。
df4 <- merge(df2, df1, all.x=TRUE); df4
# X Y W Z
#1 1 <NA> -1 NA # <-- this guy could not match, since Y was NA
#2 2 b -2 20
#3 2 c -3 30
#4 4 d -4 NA
ind <- df4$X[is.na(df4$Z)] # returns the indices 1 4
df4$Z[ind] <- df1$Z[ind]
df4
# X Y W Z
#1 1 <NA> -1 10
#2 2 b -2 20
#3 2 c -3 30
#4 4 d -4 NA
如果df2$Y对任何复制的X都包含NA,则解是不确定的。
发布于 2020-06-25 22:34:40
看起来不是最优雅的,但我不知道如何做(好)条件连接:
full_join(df2, df1, by = c("X", "Y")) %>%
filter(!is.na(W)) %>%
group_by(grp = is.na(Y)) %>%
do({
dat <- .
if (is.na(dat$Y[1])) {
left_join(dat, select(df1, -Y), by = "X") %>%
mutate(Z = coalesce(Z.x, Z.y)) %>%
select(-starts_with("Z."))
} else dat
}) %>%
ungroup() %>%
select(-grp) %>%
arrange(X, Y)
# # A tibble: 4 x 4
# X Y W Z
# <dbl> <chr> <dbl> <dbl>
# 1 1 <NA> -1 10
# 2 2 b -2 20
# 3 2 c -3 30
# 4 4 d -4 NA
https://stackoverflow.com/questions/62585174
复制