Использование функций из нескольких столбцов в вызове dplyr mutate_at
Я хотел бы использовать функцию dplyr mutate_at
чтобы применить функцию к нескольким столбцам в кадре данных, где функция вводит столбец, к которому она применяется, а также другой столбец в кадре данных.
В качестве конкретного примера, я бы посмотрел, чтобы изменить следующий фрейм данных
# Example input dataframe
df <- data.frame(
x = c(TRUE, TRUE, FALSE),
y = c("Hello", "Hola", "Ciao"),
z = c("World", "ao", "HaOlam")
)
с вызовом mutate_at
который выглядит примерно так
df %>%
mutate_at(.vars = vars(y, z),
.funs = ifelse(x, ., NA))
вернуть фрейм данных, который выглядит примерно так
# Desired output dataframe
df2 <- data.frame(x = c(TRUE, TRUE, FALSE),
y_1 = c("Hello", "Hola", NA),
z_1 = c("World", "ao", NA))
Требуемый вызов mutate_at
будет похож на следующий вызов mutate
:
df %>%
mutate(y_1 = ifelse(x, y, NA),
z_1 = ifelse(x, z, NA))
Я знаю, что это может быть сделано в базе R несколькими способами, но я бы специально хотел достичь этой цели, используя функцию dplyr mutate_at
для удобства чтения, взаимодействия с базами данных и т.д.
Ниже приведены некоторые аналогичные вопросы, задаваемые в stackoverflow, которые не относятся к вопросу, который я поставил здесь:
добавление нескольких столбцов в вызов dplyr mutate
dplyr :: mutate для добавления нескольких значений
Использование столбца внутри функции sum() с использованием функции dplyr mutate()
Ответы
Ответ 1
На этот вопрос ответил @eipi10 в комментарии @eipi10 по этому вопросу, но я пишу это здесь для потомков.
Решение здесь заключается в использовании:
df %>%
mutate_at(.vars = vars(y, z),
.funs = list(~ ifelse(x, ., NA)))
Использование list(~...)
здесь указывает, что ifelse(x,., NA)
является анонимной функцией, которая определяется в вызове mutate_at()
.
Это работает аналогично определению функции вне вызова mutate_at()
, например так:
temp_fn <- function(input) ifelse(test = df[["x"]],
yes = input,
no = NA)
df %>%
mutate_at(.vars = vars(y, z),
.funs = temp_fn)
Примечание об изменениях синтаксиса в dplyr: до версии 0.8.0 dplyr вы просто писали .funs = funs(ifelse(x,., NA))
, но функция funs()
устарела и скоро будет удалена из dplyr,
Ответ 2
В дополнение к предыдущему ответу, если вы хотите, чтобы mutate_at()
добавляла новые переменные (вместо замены) с именами, такими как z_1
и y_1
как в исходном вопросе, вам просто нужно добавить имя в funs(newname=...)
вызов:
df %>%
mutate_at(.vars = vars(y, z),
.funs = funs('1'=ifelse(x, ., NA)))
Это дает:
# A tibble: 3 x 5
x y z y_1 z_1
<lgl> <chr> <chr> <chr> <chr>
1 TRUE Hello World Hello World
2 TRUE Hola ao Hola ao
3 FALSE Ciao HaOlam NA NA
Дополнительные сведения и приемы см. В разделе: создание новых переменных с помощью mutate_at с сохранением исходных