We can use tidyverse
approach. Loop through the rows with pmap
, remove the NA
elements with na.omit
and paste
the rows together
library(tidyverse)
dat %>%
mutate_all(as.character) %>%
mutate(col3 = pmap_chr(., ~ c(...) %>%
na.omit %>%
paste(collapse="; ")))
# col1 col2 col3
#1 stuff things stuff; things
#2 stuff <NA> stuff
#3 stuff things stuff; things
#4 <NA> things things
#5 <NA> <NA>
Or another option is
dat %>%
mutate_all(as.character) %>%
mutate(col3 = case_when(is.na(col1)|is.na(col2) ~
coalesce(col1, col2),
TRUE ~ str_c(pmin(col1, col2, na.rm = TRUE),
pmax(col1, col2, na.rm = TRUE), sep="; ")))
# col1 col2 col3
#1 stuff things stuff; things
#2 stuff <NA> stuff
#3 stuff things stuff; things
#4 <NA> things things
#5 <NA> <NA> <NA>
Or using a vectorized approach with base R
i1 <- !!rowSums(!is.na(dat))
dat$col3[i1] <- gsub("^NA;|; NA", "", do.call(paste, c(dat[i1,], sep="; ")))
dat
# col1 col2 col3
#1 stuff things stuff; things
#2 stuff <NA> stuff
#3 stuff things stuff; things
#4 <NA> things things
#5 <NA> <NA> <NA>