James Martherus
James Martherus

Reputation: 1043

"collapsing" multiple factors into a single character variable

I have several non-overlapping factor variables and want to collapse them into one character variable. For example, I have this:

tibble(var1 = factor(c(1,2,3,NA,NA,NA,NA,NA,NA)),
          var2 = factor(c(NA,NA,NA,4,5,6,NA,NA,NA)),
          var3 = factor(c(NA,NA,NA,NA,NA,NA,"seven","eight","nine")))

# A tibble: 9 x 3
  var1  var2  var3 
  <fct> <fct> <fct>
1 1     NA    NA   
2 2     NA    NA   
3 3     NA    NA   
4 NA    4     NA   
5 NA    5     NA   
6 NA    6     NA   
7 NA    NA    seven
8 NA    NA    eight
9 NA    NA    nine 

and I want to generate var4:

    # A tibble: 9 x 4
  var1  var2  var3  var4 
  <fct> <fct> <fct> <chr>
1 1     NA    NA    1    
2 2     NA    NA    2    
3 3     NA    NA    3    
4 NA    4     NA    4    
5 NA    5     NA    5    
6 NA    6     NA    6    
7 NA    NA    seven seven
8 NA    NA    eight eight
9 NA    NA    nine  nine

Upvotes: 2

Views: 103

Answers (3)

ThomasIsCoding
ThomasIsCoding

Reputation: 101064

Perhaps this could help you

df$var4 <- na.omit(unlist(df))

such that

> df
# A tibble: 9 x 4
  var1  var2  var3  var4
  <fct> <fct> <fct> <fct>
1 1     NA    NA    1
2 2     NA    NA    2
3 3     NA    NA    3
4 NA    4     NA    4    
5 NA    5     NA    5
6 NA    6     NA    6
7 NA    NA    seven seven
8 NA    NA    eight eight
9 NA    NA    nine  nine

A data.table option with fcoalesce

> setDT(df)[, var4 := do.call(fcoalesce, Map(as.charac .... [TRUNCATED]
   var1 var2  var3  var4
1:    1 <NA>  <NA>     1
2:    2 <NA>  <NA>     2
3:    3 <NA>  <NA>     3
4: <NA>    4  <NA>     4
5: <NA>    5  <NA>     5
6: <NA>    6  <NA>     6
7: <NA> <NA> seven seven
8: <NA> <NA> eight eight
9: <NA> <NA>  nine  nine

Upvotes: 0

TarJae
TarJae

Reputation: 78917

We could use unite from tidyr

df %>% 
  unite(var4, var1:var3, remove = F,  na.rm = TRUE) %>% 
  select(var1, var2, var3, var4)

Output:

  var1  var2  var3  var4 
  <fct> <fct> <fct> <chr>
1 1     NA    NA    1    
2 2     NA    NA    2    
3 3     NA    NA    3    
4 NA    4     NA    4    
5 NA    5     NA    5    
6 NA    6     NA    6    
7 NA    NA    seven seven
8 NA    NA    eight eight
9 NA    NA    nine  nine 

Upvotes: 3

akrun
akrun

Reputation: 886938

We can use coalesce

library(dplyr)
df1 %>%
    mutate(var4 = coalesce(!!! .))
    # // or use
    # mutate(var4 = purrr::reduce(., coalesce))

-output

# A tibble: 9 x 4
#  var1  var2  var3  var4 
#  <fct> <fct> <fct> <fct>
#1 1     <NA>  <NA>  1    
#2 2     <NA>  <NA>  2    
#3 3     <NA>  <NA>  3    
#4 <NA>  4     <NA>  4    
#5 <NA>  5     <NA>  5    
#6 <NA>  6     <NA>  6    
#7 <NA>  <NA>  seven seven
#8 <NA>  <NA>  eight eight
#9 <NA>  <NA>  nine  nine 

Upvotes: 2

Related Questions