Unnest group of string across columns but keep them in the original row in R

Viewed 372

I'm trying to find a way to unnest the group of string across columns but keep all the string in the original row. Take the example dataset starwars from dplyr as it has similar strcuture of my dataset.

The starwars dataset has 3 nested columns of films, vehicles, starships. The common approach is to do a unnest_longer so we unnest the group of string into multiple rows - each row contains one piece of the string. However, I'd prefer to keep all the ungrouped string in the original row.

The alternative approach is to use rowwise() and mutate with paste. This works but my dataset has 15 nested columns so I'd have to type 15 line of mutate with paste. That's a bit tedious.

df <- dplyr::starwars %>%
  rowwise() %>%
  mutate(films = paste(films, collapse=', '),
         vehicles = paste(vehicles, collapse=', '),
         starships = paste(starships, collapse=', '))

My current thinking is to come up with a wrap function and perhaps I can do it through purrr at scale. But my poor function writing is not working - perhaps I am not too familiar with the dplyr hood.

ungroup_string <- function(data, x){
  a <- rowwise(data)
  a %>% mutate(x = paste(x, collapse=','))
}

Any way I can do this ungroup string across a number of columns?

1 Answers

You can use across :

library(dplyr)

starwars %>%
  select(name, films, vehicles, starships) %>%
  rowwise() %>%
  mutate(across(c(films,vehicles, starships), toString))

#    name       films                                vehicles         starships                             
#   <chr>      <chr>                                <chr>            <chr>                                 
# 1 Luke Skyw… The Empire Strikes Back, Revenge of… "Snowspeeder, I… "X-wing, Imperial shuttle"            
# 2 C-3PO      The Empire Strikes Back, Attack of … ""               ""                                    
# 3 R2-D2      The Empire Strikes Back, Attack of … ""               ""                                    
# 4 Darth Vad… The Empire Strikes Back, Revenge of… ""               "TIE Advanced x1"                     
# 5 Leia Orga… The Empire Strikes Back, Revenge of… "Imperial Speed… ""                                    
# 6 Owen Lars  Attack of the Clones, Revenge of th… ""               ""                                    
# 7 Beru Whit… Attack of the Clones, Revenge of th… ""               ""                                    
# 8 R5-D4      A New Hope                           ""               ""                                    
# 9 Biggs Dar… A New Hope                           ""               "X-wing"                              
#10 Obi-Wan K… The Empire Strikes Back, Attack of … "Tribubble bong… "Jedi starfighter, Trade Federation c…
# … with 77 more rows

across accepts tidy-select variables. So you don't have to specify each of your 15 columns one by one. You can select column names by position 1:15, by range col1:col15 or by some pattern in their name starts_with('col').

Related