Для result_1 вы можете использовать left_join
и case_when
после преобразования в длинную форму:
library(dplyr)
library(tidyr)
left_join(pivot_longer(df1, -starts_with('id_col'),
values_ptypes=list(value='character')),
pivot_longer(df2, -starts_with('id_col'), values_to="value2",
values_ptypes=list(value2='character'))) %>%
mutate(value = case_when(value == '' ~ value2,
TRUE ~ value)) %>%
select(-value2) %>%
pivot_wider() %>%
type.convert()
# id_col1 id_col2 name age sex
# <int> <fct> <fct> <int> <fct>
# 1 101 1M Steve 21 M
# 2 101 3M Steve 21 M
# 3 102 1M Mark 25 M
Для result_2 код аналогичен, за исключением мутации, мы фильтруем и добавляем дополнительную форму.
left_join(pivot_longer(df1, -starts_with('id_'), values_to="value1",
values_ptypes=list(value1='character')),
pivot_longer(df2, -starts_with('id_'), values_to="value2",
values_ptypes=list(value2='character'))) %>%
filter(value1 != '' & value2 != '' & value1 != value2) %>%
pivot_longer(cols=value1:value2, names_prefix="value", names_to="df") %>%
pivot_wider() %>%
type.convert() %>%
select(intersect(names(df1), names(.))) # to retain original colname ordering
# id_col1 id_col2 name age
# <int> <fct> <fct> <int>
# 1 101 3M NA 21
# 2 101 3M NA 25
# 3 102 1M Mark NA
# 4 102 1M Ria NA
Data :
df1 <- structure(list(id_col1 = c(101L, 101L, 102L), id_col2 = c("1M",
"3M", "1M"), name = c("", "", "Mark"), age = c(21L, 21L, 25L),
sex = c("", "M", "")), class = "data.frame", row.names = c(NA, -3L))
df2 <- structure(list(id_col1 = c(101L, 101L, 101L, 102L, 102L), id_col2 = c("1M",
"2M", "3M", "1M", "2M"), name = c("Steve", "", "Steve", "Ria",
"Anie"), age = c(NA, NA, 25L, 25L, 22L), sex = c("M", "M", "",
"M", "F")), class = "data.frame", row.names = c(NA, -5L))