Struggling to find an elegant solution to this...
I have responses to "please select all that apply" questions, where each of choices A to F per question are coded as binary variables. So, for example, the first responder in the fake dataset below ticked only D for question 1, then A,C,D and E for question 2.
library(dplyr)
cols <- paste0('foo', '_', c(1:2, '3a', '3b')) %>%
lapply(\(i) paste0(i, '_', LETTERS[1:6])) %>%
unlist()
set.seed(1)
df <- lapply(cols, \(i) i = sample(0:1, 5, replace = TRUE)) %>%
setNames(cols) %>%
data.frame()
'data.frame': 5 obs. of 24 variables:
$ foo_1_A : int 0 1 0 0 1
$ foo_1_B : int 0 0 0 1 1
$ foo_1_C : int 0 0 0 0 0
$ foo_1_D : int 1 1 1 1 0
$ foo_1_E : int 0 0 0 0 0
$ foo_1_F : int 0 1 0 0 1
$ foo_2_A : int 1 1 0 1 0
$ foo_2_B : int 0 1 0 1 1
$ foo_2_C : int 1 1 0 1 1
$ foo_2_D : int 1 1 1 0 0
$ foo_2_E : int 1 0 1 1 0
$ foo_2_F : int 0 1 1 1 0
$ foo_3a_A: int 0 1 1 1 1
$ foo_3a_B: int 1 1 0 1 1
$ foo_3a_C: int 1 1 0 0 0
$ foo_3a_D: int 1 1 0 0 1
$ foo_3a_E: int 1 1 0 0 0
$ foo_3a_F: int 1 0 1 0 1
$ foo_3b_A: int 0 0 1 1 0
$ foo_3b_B: int 0 0 1 1 0
$ foo_3b_C: int 1 1 1 0 0
$ foo_3b_D: int 0 0 1 0 0
$ foo_3b_E: int 0 0 0 1 1
$ foo_3b_F: int 1 1 0 1 1
What I want is to recode 1
to each column's choice-letter (A
, B
, C
, D
, E
, or F
) and to concatenate the choices for each question so that I have something like this:
foo_1 D ADF D BD ABF
foo_2 ACDE ABCDF DEF ABCEF BC
foo_3a BCDEF ABCDE AF AB ABDF
foo_3b CF CF ABCD ABEF EF
This is as far as I got before realising I'd get stuck repeating similar code over and over:
df <- df %>% mutate(across(
starts_with('foo') & ends_with('A'),
~ recode(., `1` = 'A', .default = NA_character_)
))