Home > front end >  Tidyverse method for combining sets of columns based on a condition in the column names
Tidyverse method for combining sets of columns based on a condition in the column names

Time:09-30

Imagine I have the following columns (among others) in my dataframe (credit to Allan for creating the sample data):

20L, 15L), b_years = c(4L, 5L, 3L), b_months = 0:2, b_days = c(10L, 
8L, 6L), c_years = 8:6, c_months = c(11L, 9L, 8L), c_days = c(26L, 
19L, 18L)), class = "data.frame", row.names = c(NA, -3L))

df
#>   a_years a_months a_days b_years b_months b_days c_years c_months c_days
#> 1       5        6     23       4        0     10       8       11     26
#> 2       4        7     20       5        1      8       7        9     19
#> 3       3        8     15       3        2      6       6        8     18

And I want to combine columns that start with the same grouping key (in this case the letter at the beginning, but in my data it's a longer expression) such that I get columns a_days, b_days, c_days and so on with values in eahc column equal to x_years * 365 x_months * 30 x_days, for each group (a, b, c, d, e and so on) of columns.

Is there a way to accomplish this all at once? Some combination of map() and mutate() comes to mind, or maybe using case_when(), but I can't quite figure it out. Thanks for any guidance you can offer!

CodePudding user response:

You can do this with across inside transmute:

library(dplyr)


df %>% 
  transmute(across(contains("days"),   ~ .x)       
            across(contains("months"), ~ .x * 30)  
            across(contains("years"),   ~ .x * 365)) 
#>   a_days b_days c_days
#> 1   2028   1470   3276
#> 2   1690   1863   2844
#> 3   1350   1161   2448

Sample data

df <- structure(list(a_years = 5:3, a_months = 6:8, a_days = c(23L, 
20L, 15L), b_years = c(4L, 5L, 3L), b_months = 0:2, b_days = c(10L, 
8L, 6L), c_years = 8:6, c_months = c(11L, 9L, 8L), c_days = c(26L, 
19L, 18L)), class = "data.frame", row.names = c(NA, -3L))

df
#>   a_years a_months a_days b_years b_months b_days c_years c_months c_days
#> 1       5        6     23       4        0     10       8       11     26
#> 2       4        7     20       5        1      8       7        9     19
#> 3       3        8     15       3        2      6       6        8     18

Created on 2022-09-29 with reprex v2.0.2

  •  Tags:  
  • r
  • Related