4

Say I create a data frame, foo:

foo <- data.frame(A=rep(NA,10),B=rep(NA,10))
foo$A[1:3] <- "A"
foo$B[6:10] <- "B"

which looks like,

      A    B
1     A <NA>
2     A <NA>
3     A <NA>
4  <NA> <NA>
5  <NA> <NA>
6  <NA>    B
7  <NA>    B
8  <NA>    B
9  <NA>    B
10 <NA>    B

I can coalesce this into a single column, like this:

data.frame(AB = coalesce(foo$A, foo$B))

giving,

     AB
1     A
2     A
3     A
4  <NA>
5  <NA>
6     B
7     B
8     B
9     B
10    B

which is nice. Now, say my data frame is huge with lots of columns. How do I coalesce that without naming each column individually? As far as I understand, coalesce is expecting vectors, so I don't see a neat and tidy dplyr solution where I can just pluck out the required columns and pass them en masse. Any ideas?

EDIT

As requested, a "harder" example.

foo <- data.frame(A=rep(NA,10),B=rep(NA,10),C=rep(NA,10),D=rep(NA,10),E=rep(NA,10),F=rep(NA,10),G=rep(NA,10),H=rep(NA,10),I=rep(NA,10),J=rep(NA,10))
foo$A[1] <- "A"
foo$B[2] <- "B"
foo$C[3] <- "C"
foo$D[4] <- "D"
foo$E[5] <- "E"
foo$F[6] <- "F"
foo$G[7] <- "G"
foo$H[8] <- "H"
foo$I[9] <- "I"
foo$J[10] <- "J"

How do I coalesce this without having to write:

data.frame(ALL= coalesce(foo$A, foo$B, foo$C, foo$D, foo$E, foo$F, foo$G, foo$H, foo$I, foo$J))
Dan
  • 11,370
  • 4
  • 43
  • 68
  • Can you give a reproducible example of a harder case? The solution will depend on how your data is arranged. – alistaire Jun 30 '17 at 17:27
  • Not really, as it's essentially just the case that I gave, but with lots of columns. One important point, however, is that there are no cases where the values in each column overlap with one another. That is to say, there are no rows that contain As **and** Bs, etc. But – like in the example above – there are rows with no values (e.g., rows 4 and 5). – Dan Jun 30 '17 at 17:36
  • Let me rephrase: you _need_ to edit with [a reproducible minimal example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example#5963610) for your question to be answerable. You've already got the example you give working, which makes it non-representative. – alistaire Jun 30 '17 at 17:39

2 Answers2

4

You can use do.call(coalesce, ...), which is a simpler way to write a function call with a lot of arguments:

library(dplyr)
do.call(coalesce, foo)
# [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J"
Psidom
  • 209,562
  • 33
  • 339
  • 356
2

You can use this (documentation of purrr: pmap)

coalesce(!!!foo)
Alvaro Morales
  • 1,845
  • 3
  • 12
  • 21