У меня есть набор данных, в котором множество столбцов имеют символы NA
, потому что они зависят от ответа другого столбца. Например :
df <- data.frame(X_home = c("Yes", "Yes", "No"),
X_school = c("No", "Yes", "No"),
Y_home = c("A", "B", NA),
Y_school = c(NA, "A", NA))
Если я использую mutate()
, я могу сделать:
df %>% mutate(Y_home = if_else(X_home == "No", "C", Y_home),
Y_school = if_else(X_school == "No", "C", Y_school))
чтобы получить то, что я хочу. Но проблема в том, что у меня много X_something
и Y_something
. Поэтому я хотел бы сделать это с чем-то вроде этого:
df %>% mutate(across(starts_with("Y_"), ~ if_else(...))
Является ли это возможным ?
Большое спасибо.
Мы можем get
значение соответствующего столбца после замены подстроки имени столбца (cur_column()
) с помощью str_replace
library(dplyr)
library(stringr)
df %>%
mutate(across(starts_with("Y_"),
~ case_when(get(str_replace(cur_column(), "Y_", "X_")) == "No" ~
"C", TRUE ~ .x)))
-выход
X_home X_school Y_home Y_school
1 Yes No A C
2 Yes Yes B A
3 No No C C
Вот один из возможных подходов с поворотом:
Мы идентифицируем группы из двух в длинном формате, чтобы имитировать соответствующие пары столбцов.
Внутри этих групп мы mutate
across
school
и home
и возвращаемся назад:
library(tidyr)
library(dplyr)
df %>%
mutate(rn = row_number()) %>%
pivot_longer(cols = -rn, names_to = c( "grp", '.value'), names_sep = "\\_") %>%
group_by(rn) %>%
mutate(across(c(home, school), ~ if_else(is.na(.), "C",.))) %>%
pivot_wider(names_from = grp,
values_from = c(home, school),
names_glue = "{grp}_{.value}") %>%
ungroup() %>%
select(-rn)
X_home Y_home X_school Y_school
<chr> <chr> <chr> <chr>
1 Yes A No C
2 Yes B Yes A
3 No C No C