简体   繁体   中英

How to create new column with all non-NA values from multiple other columns?

I would like to create a column d, which includes all the non-NA values from the other columns.

I tried ifelse, but cannot figure out how to make it nested in the proper manner, so that the value in column c is included as well.. Perhaps something else than ifelse should be used?

Here is a "dummy" dataframe:

 a <- c(NA, NA, NA, "A", "B", "A", NA, NA)
 b <- c("D", "A", "C", NA, NA, NA, NA, NA)
 c <- c(NA, NA, NA, NA, NA, NA, "C", NA)
 data <- data.frame(a, b, c)

I would like the d column to look like this:

 data$d <- c("D", "A", "C", "A", "B", "A", "C", NA)
 View(data)

We can use pmax

do.call(pmax, c(data, list(na.rm=TRUE)))
#[1] "D" "A" "C" "A" "B" "A" "C" NA 

data

data <- data.frame(a, b, c, stringsAsFactors=FALSE)

Here is a bit ugly idea assuming that you only have one non-NA value in each row,

data$d <- apply(data, 1, function(i) ifelse(all(is.na(i)), NA, i[!is.na(i)]))
data
#     a    b    c    d
#1 <NA>    D <NA>    D
#2 <NA>    A <NA>    A
#3 <NA>    C <NA>    C
#4    A <NA> <NA>    A
#5    B <NA> <NA>    B
#6    A <NA> <NA>    A
#7 <NA> <NA>    C    C
#8 <NA> <NA> <NA> <NA>

I also found this workaround, but I'm not sure I like it:

data <- as.matrix(data)
data[is.na(data)] <- " "
data <- data.frame(data)
data$d <- with(data, paste0(a, b, c), na.rm=TRUE)
View(data)

Turns out that should've just out in "" and not " " in NA cells.

And if the space is not avoidable use trimws on the column of the dataframe to remove them afterwards:

  data$d <- trimws(data$d)

I was working on a similar problem much later in time and thought I would provide a more generalizable solution using dplyr and stringr .

library(tidyverse)
a <- c(NA, NA, NA, "A", "B", "A", NA, NA)
b <- c("D", "A", "C", NA, NA, NA, NA, NA)
c <- c(NA, NA, NA, NA, NA, NA, "C", NA)
data <- data.frame(a, b, c)

data %>% 
  mutate_all(stringr::str_replace_na, replacement = "") %>% 
  mutate(d = stringr::str_c(a,b,c)) %>%
  mutate_all(stringr::str_replace, pattern = "^$", replacement = NA_character_)
#>      a    b    c    d
#> 1 <NA>    D <NA>    D
#> 2 <NA>    A <NA>    A
#> 3 <NA>    C <NA>    C
#> 4    A <NA> <NA>    A
#> 5    B <NA> <NA>    B
#> 6    A <NA> <NA>    A
#> 7 <NA> <NA>    C    C
#> 8 <NA> <NA> <NA> <NA>

Created on 2019-05-06 by the reprex package (v0.2.1)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM