干净地粘贴包含NA的列

时间:2019-05-24 21:26:10

标签: r

我正在尝试将2个文本列粘贴在一起。问题在于每一列中的某些值都是NA,如果是这种情况,我不希望将NA作为粘贴字符串的一部分。这是我的意思的一个例子

一些数据:

dat <- data.frame("col1" = c("stuff", "stuff", "stuff", NA, NA),
           "col2" = c("things", NA, "things", "things", NA))

dat

   col1   col2
1 stuff things
2 stuff   <NA>
3 stuff things
4  <NA> things
5  <NA>   <NA>

这就是我需要的:

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>

我可以使用paste(),然后使用gsub()清理混乱,但我一直在寻找更好的单层纸。

谢谢

2 个答案:

答案 0 :(得分:3)

这是使用基数R的一种方法-

dat$col3 <- apply(dat, 1, function(x) paste0(na.omit(x), 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>              

答案 1 :(得分:1)

我们可以使用tidyverse方法。用pmap遍历行,用NAna.omit一起删除paste元素

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>   

或者另一个选择是

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>

或与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>