I have two columns called Apple and Pear. If the text in these columns say "Yes" or "No", I want this text to be replaced with the column name. The desired result is shown in the fields Apple2 and Pear2 in the example.
Apple<-c("Yes","No", "Yes", "Other", NA)
Pear<-c("Yes",NA, "No", "Other","Yes")
Apple2<-c("Apple","Apple","Apple","Other",NA)
Pear2<-c("Pear",NA,"Pear","Other","Pear")
data<-data.frame(Apple,Pear,Apple2,Pear2, stringsAsFactors = FALSE)
Can anyone suggest a way of achieving this?
CodePudding user response:
With dplyr, across, it can be done by getting the column name i.e. cur_column() with a conditional expression in ifelse/case_when
library(dplyr)
data <- data %>%
mutate(across(c(Apple, Pear),
~ case_when(.x %in% c("Yes", "No") ~ cur_column(), TRUE ~ .x)))
-output
data
Apple Pear Apple2 Pear2
1 Apple Pear Apple Pear
2 Apple <NA> Apple <NA>
3 Apple Pear Apple Pear
4 Other Other Other Other
5 <NA> Pear <NA> Pear
CodePudding user response:
My answer is conceptually the same as @akrun's. What's different is that I assume your input data only has two columns. Therefore in your across, you need to use .names to set the column names of newly created ones. Also, we need to specify what to do if .x == "Others" in case_when.
library(dplyr)
Apple<-c("Yes","No", "Yes", "Other", NA)
Pear<-c("Yes",NA, "No", "Other","Yes")
data<-data.frame(Apple,Pear)
data %>%
mutate(across(everything(),
~case_when(.x == "Other" ~ "Other",
.x %in% c("Yes", "No") ~ cur_column(),
TRUE ~ NA_character_),
.names = "{.col}2"))
Apple Pear Apple2 Pear2
1 Yes Yes Apple Pear
2 No <NA> Apple <NA>
3 Yes No Apple Pear
4 Other Other Other Other
5 <NA> Yes <NA> Pear
CodePudding user response:
Here's another option using imap_dfr from purrr:
library(tidyverse)
imap_dfr(data, ~ replace(.x, .x %in% c("Yes", "No"), .y))
Output
Apple Pear Apple2 Pear2
<chr> <chr> <chr> <chr>
1 Apple Pear Apple Pear
2 Apple NA Apple NA
3 Apple Pear Apple Pear
4 Other Other Other Other
5 NA Pear NA Pear
Or another option using transmute:
data %>%
transmute(across(everything(), ~ ifelse(
.x %in% c("Yes", "No"), deparse(substitute(.)), .
)))
Data
data <- structure(list(Apple = c("Yes", "No", "Yes", "Other", NA), Pear = c("Yes",
NA, "No", "Other", "Yes"), Apple2 = c("Apple", "Apple", "Apple",
"Other", NA), Pear2 = c("Pear", NA, "Pear", "Other", "Pear")), class = "data.frame", row.names = c(NA,
-5L))
