I want to join/merge two data sets based on 2 variables of the second data set.
Described in words, I want to join based on variable 1 ( VAR1
) and if this results in NA
join with variable 2 ( VAR2
).
Here's an example and my solution to this:
df_x <- data.frame(VAR0=c("A","P","C","D","Z"), stringsAsFactors = F)
df_y <- data.frame(VAR1=c("A","B","C","D","E"),
VAR2=c("A","F","T","D","Z"),
VAR3=c("YES", "YES", "NO", "MAYBE", "YES"),
stringsAsFactors = F)
require(dplyr)
# LEFT JOIN TWICE TO MEET BOTH CONDITIONS
lj_1 <- left_join(df_x, df_y, by=c("VAR0" = "VAR1"))
lj_2 <- left_join(df_x, df_y, by=c("VAR0" = "VAR2"))
# THEN REPLACE NAs FROM FIRST LEFT JOIN WITH VALUE FROM SECOND LEFT JOIN
ifelse(lj_1$VAR3 %in% NA, lj_2$VAR3, lj_1$VAR3)
# [1] "YES" NA "NO" "MAYBE" "YES"
I was wondering if there is a better way to do that?
We can do the left_join
in a loop and reduce
it to a single vector
by applying coalesce
on the 'VAR3'
library(tidyverse)
map(paste0("VAR", 1:2), ~
left_join(df_x, df_y, by = c("VAR0" = .x)) %>%
pull(VAR3)) %>%
reduce(coalesce)
#[1] "YES" NA "NO" "MAYBE" "YES"
Or using base R
pmin(df_y$VAR3[match(df_x$VAR0, df_y$VAR1)],
df_y$VAR3[match(df_x$VAR0, df_y$VAR2)], na.rm = TRUE)
#[1] "YES" NA "NO" "MAYBE" "YES"
Or to avoid using the df
calls, use with
with(df_y, with(df_x, pmin(VAR3[match(VAR0, VAR1)],
VAR3[match(VAR0, VAR2)], na.rm = TRUE)))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.