4

I have data similar to the following:

a<-data.frame(pig=c(NA,"a","b","c",NA),cow=c(NA,"101","112","77",NA),chicken=c("Sep",NA,"Oct","Nov",NA),stringsAsFactors=FALSE)
print(a)
pig  cow chicken
<NA> <NA>   Sep
 a  101    <NA>
 b  112     Oct
 c   77     Nov
<NA> <NA>  <NA>

I am attempting to paste the columns together and obtain NA if any NA is present in any of the paste columns for a given observation such as:

pig  cow chicken   rooster
<NA> <NA>   Sep     <NA>
 a   101    <NA>    <NA>
 b   112    Oct   b-112-Oct
 c   77     Nov   c-77-Nov
<NA> <NA>   <NA>    <NA>

I have used the following

a$rooster<-paste(a$pig,a$cow,a$chicken,sep="-")

This yields strings that include NAs as part of the string, which is not ideal. The documentation I have seen does not explicitly address this issue, such as: suppress NAs in paste() Any thoughts? Thanks!

costebk08
  • 1,299
  • 4
  • 17
  • 42

2 Answers2

3

stringr::str_c has "infectious" NAs

paste('a', 'b', NA)
#> [1] "a b NA"

stringr::str_c('a', 'b', NA)
#> [1] NA
Paul
  • 8,734
  • 1
  • 26
  • 36
  • I like this approach as well, you could modify my solution to be `a %>% mutate(rooster = stringr::str_c(pig, cow, chicken, sep = "-"))` and produce the same result. – Kevin Arseneau Jan 25 '18 at 00:36
1

You can use an ifelse or case_when approach if we are using the tidyverse packages.

library(dplyr)

a <- data.frame(
  pig = c(NA, "a", "b", "c", NA),
  cow = c(NA, "101", "112", "77", NA),
  chicken = c("Sep", NA, "Oct", "Nov", NA),
  stringsAsFactors = FALSE
)

a %>%
  mutate(
    rooster = case_when(
      is.na(pig) | is.na(cow) | is.na(chicken) ~ NA_character_,
      TRUE ~ paste(pig, cow, chicken, sep = "-")
    )
  )

#    pig  cow chicken   rooster
# 1 <NA> <NA>     Sep      <NA>
# 2    a  101    <NA>      <NA>
# 3    b  112     Oct b-112-Oct
# 4    c   77     Nov  c-77-Nov
# 5 <NA> <NA>    <NA>      <NA>
Kevin Arseneau
  • 6,186
  • 1
  • 21
  • 40