shou01
shou01

Reputation: 11

How to write an R function to combine two variables?

I would like to write a function that can combine/rewrite many similarly named variables. In plain English, I would like to change the value of var1 to the value of var1a when the observation is made in Wave 4. I have to do this 37 times, and I would like to avoid writing out basically identical lines of code 37 times.

df <- df %>% mutate(var1=case_when(wave==4~var1a))
df <- df %>% mutate(var2=case_when(wave==4~var2a))
df <- df %>% mutate(var3=case_when(wave==4~var3a))

I tried doing this... but I kept getting an error code that says that there is an unexpected = after vvar[i].

vvar <- c("var1","var2","var3")
vvara <- c("var1a","var2a","var3a")
for(i in 1:3){
  df.test <- df %>% mutate(vvar[i]=case_when(wave==4~vvara[i]))
}

I also tried the following... and the error is that the replacement has no length.

renamefunc <- function(dataset,vars1,vars2){
  for (i in 1:length(vars1)){
    dataset1 <- ifelse(dataset$wave==4,dataset$vars2[i],dataset$vars1[i])
  }
  return(dataset1)
}
z <- renamefunc(df,vvar,vvara)

Upvotes: 1

Views: 215

Answers (1)

r2evans
r2evans

Reputation: 160687

dplyr

You can use across with cur_column() and cur_data() to get what you need.

Data:

set.seed(42)
quux <- data.frame(var1=sample(5), var2=sample(5), var3=sample(5), var1a=11L, var2a=22L, var3a=31L)
quux
#   var1 var2 var3 var1a var2a var3a
# 1    1    4    4    11    22    31
# 2    5    2    1    11    22    31
# 3    4    5    5    11    22    31
# 4    3    1    2    11    22    31
# 5    2    3    3    11    22    31

And using across:

library(dplyr)
quux %>%
  mutate(across(matches("^var[0-9]+$"), ~ if_else(. == 4, cur_data()[[ paste0(cur_column(), "a") ]], .)))
#   var1 var2 var3 var1a var2a var3a
# 1    1   22   31    11    22    31
# 2    5    2    1    11    22    31
# 3   11    5    5    11    22    31
# 4    3    1    2    11    22    31
# 5    2    3    3    11    22    31

base R

qvars <- grep("^var[0-9]+$", names(quux), value = TRUE)
qvarsa <- paste0(qvars, "a")
quux[qvars] <- Map(function(a, b) ifelse(a == 4, b, a), quux[qvars], quux[qvarsa])
quux
#   var1 var2 var3 var1a var2a var3a
# 1    1   22   31    11    22    31
# 2    5    2    1    11    22    31
# 3   11    5    5    11    22    31
# 4    3    1    2    11    22    31
# 5    2    3    3    11    22    31

Upvotes: 1

Related Questions