0

I was wondering if there was a way to construction a function to do the following:

Original dataframe, df:

Obs Col1    Col2
1   Y       NA
2   NA      Y
3   Y       Y

Modified dataframe, df:

Obs Col1 Col2 Col1_YN Col2_YN
1   Y    NA   “Yes”   “No”
2   NA   Y    “No     “Yes”
3   Y    Y    “Yes”   “Yes”

The following code works just fine to create the new variables but I have lots of original columns with this structure and the “Yes” “No” format works better when constructing tables.

df$Col1_YN <- as.factor(ifelse(is.na(df$Col1), “No”, “Yes”))
df$Col2_YN <- as.factor(ifelse(is.na(df$Col2), “No”, “Yes”))

I was thinking along the lines of defining lists of input and output columns to be passed to a function, or using lapply but haven’t figured out how to do this.

1 Answer 1

4

We can use across to loop over the columns and create the new columns by modifying the .names

library(dplyr)
df1 <- df %>% 
   mutate(across(-Obs,  
   ~ case_when(. %in% "Y" ~ "Yes", TRUE ~ "No"), .names = "{.col}_YN"))

-output

df1
  Obs Col1 Col2 Col1_YN Col2_YN
1   1    Y <NA>     Yes      No
2   2 <NA>    Y      No     Yes
3   3    Y    Y     Yes     Yes

If we want to use lapply, loop over the columns of interest, apply the ifelse and assign it back to new columns by creating a vector of new names with paste

df[paste0(names(df)[-1], "_YN")] <- 
   lapply(df[-1], \(x) ifelse(is.na(x), "No", "Yes"))

data

df <- structure(list(Obs = 1:3, Col1 = c("Y", NA, "Y"), Col2 = c(NA, 
"Y", "Y")), class = "data.frame", row.names = c(NA, -3L))
Sign up to request clarification or add additional context in comments.

2 Comments

Is there a way to define a list of input columns for ".names" in your answer. Ex: Initial column names: "Tobacco", "Alcohol", "Fentanyl" etc. with new output columns as "Tobacco_YN", "Alcohol_YN", "Fentanyl_YN" etc.?
@B.Koch it should be mentioned in across i.e. across(c(Tobacco, Alcohol, Fentanyl), ~ case_when(. %in% "Y" ~ "Yes", TRUE ~ "No"), .names = "{.col}_YN"))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.