Search code examples
rdplyrpiping

Fuse multiple data.frame date fields by removing NA using piping


I want to fuse multiple date fields that contains NAs using piping in R. The data looks like:

dd <- data.frame(id=c("a","b","c","d"),
                  f1=as.Date(c(NA, "2012-03-24", NA,NA)),
                  f2=as.Date(c("2010-01-24", NA, NA,NA)),
                  f3=as.Date(c(NA, NA, "2014-11-22", NA)))
 dd
  id         f1         f2         f3
1  a       <NA> 2010-01-24       <NA>
2  b 2012-03-24       <NA>       <NA>
3  c       <NA>       <NA> 2014-11-22
4  d       <NA>       <NA>       <NA>

I know how to do it the R base way:

unlist(apply(dd[,c("f1","f2","f3")],1,na.omit))
          f2           f1           f3 
"2010-01-24" "2012-03-24" "2014-11-22" 

So that is not the point of my question. I'm in the process of learning piping and dplyr so I want to pipe this function. I've tried:

library(dplyr)
dd %>% mutate(f=na.omit(c(f1,f2,f3)))
Error in mutate_impl(.data, dots) : 
  Column `f` must be length 4 (the number of rows) or one, not 3

It doesn't work because of the line with all NAs. Without this line, it would work:

dd[-4,] %>% mutate(f=na.omit(c(f1,f2,f3)))
  id         f1         f2         f3          f
1  a       <NA> 2010-01-24       <NA> 2012-03-24
2  b 2012-03-24       <NA>       <NA> 2010-01-24
3  c       <NA>       <NA> 2014-11-22 2014-11-22

Any idea how to do it properly?

BTW, my question is different from this and this as I want to use piping and because my field is a date field, I cannot use sum with na.rm=T.

Thanks


Solution

  • We can use coalesce to create the new column,

    library(dplyr)
    dd %>%
       transmute(newcol = coalesce(f1, f2, f3)) #%>%
       #then `filter` the rows to remove the NA elements 
       #and `pull` as a `vector` (if needed) 
       #filter(!is.na(newcol)) %>%
       #pull(newcol)
    #     newcol
    #1 2010-01-24
    #2 2012-03-24
    #3 2014-11-22
    #4       <NA>