1
votes
library(tidyverse)    

Using the sample code below, I want to create a new variable "Filter", that recodes the variables ending is "s" (q25s,q26s,etc...), based on the value of the corresponding non "s" variable. So for example, if q25 = 1, then q25s will be recoded so that 1 = 0, 2=0, 3=0, 4=1, 5=1, and 88=Missing. If q25 doesn't equal 1, then Filter should be 0. This pattern will be repeated for all the other sets of variables.

However, in order to achieve this I'm attempting to use tidyverse to create a named vector of column names called "cols", and then use this within a "mutate_at" function together with "if_else" and dplyr::recode.

Below is an attempt but it doesn't seem to work. How should I correct the code? I'm open to other suggestions as well as long as tidyverse is used and the code is compact and no more than two lines if possible...

cols<-c(q25:q29)

Df<-Df%>%mutate_at(vars(q25s:q29s),funs(Filter=if_else(!!cols=1,recode  (.,`1`="a",`2`="b",`3`="c",`4`="d",`5`="e"),"Missing")))

How can I achieve this using tidyverse?

Here is the sample code:

q25<-c(2,1,88,2,1)
q26<-c(2,88,88,88,2)
q27<-c(2,2,1,1,1)
q28<-c(88,1,1,2,2)
q29<-c(1,1,1,2,2)
q25s<-c(3,5,88,4,1)
q26s<-c(4,4,5,5,1)
q27s<-c(3,3,4,1,4)
q28s<-c(4,5,88,1,3)
q29s<-c(88,88,3,4,4)
Df<-data.frame(q25,q26,q27,q28,q29,q25s,q26s,q27s,q28s,q29s)
1

1 Answers

1
votes

One option would be to subset the dataset by including columns that start with 'q' followed by numbers ('q\d+') and 'q' followed by numbers followed by 's' ('q\d+s'), then with map2, use the ifelse to change the corresponding columns to letters based on value 1 in 'q\d+' columns

library(tidyverse)
cols<-paste0("q", 25:29)
cols1 <- paste0(cols, "s")
Df[cols1] <- map2(Df[cols], Df[cols1], ~ifelse(.x == 1, letters[.y], .y) %>%
                             replace(., is.na(.), "Missing") )

Df
#  q25 q26 q27 q28 q29 q25s q26s q27s    q28s    q29s
#1   2   2   2  88   1    3    4    3       4 Missing
#2   1  88   2   1   1    e    4    3       e Missing
#3  88  88   1   1   1   88    5    d Missing       c
#4   2  88   1   2   2    4    5    a       1       4
#5   1   2   1   2   2    a    1    d       3       4

Or using only base R

Df[cols1] <- Map(function(x,y) {
                 x1 <- ifelse(x == 1, letters[y], y)
                 replace(x1, is.na(x1), "Missing")
                 },
                      Df[cols], Df[cols1])