Вот несколько способов обхода цикла и if
/ else
структур с использованием dplyr::case_when
или dplyr::recode
.Обе эти функции обеспечивают векторизованные способы выполнения этой замены.Все параметры здесь имеют одинаковый вывод.
dplyr::recode
принимает набор пар ключ-значение с необязательным значением по умолчанию.Он также может принимать именованный список без кавычек !!!
, что позволяет сохранить вектор поиска.Используя apply
вместо цикла:
library(dplyr)
as.data.frame(apply(df, 1, function(x) {
recode(x,
Y = 2,
yes = 2,
always = 2,
Often = 1,
.default = 0)
}))
#> V1 V2 V3
#> 1 2 0 2
#> 2 0 2 2
#> 3 1 2 0
# with a lookup and !!!
lookup <- c(Y = 2, yes = 2, always = 2, Often = 1)
as.data.frame(apply(df, 1, function(x) recode(x, !!!lookup, .default = 0)))
Вы также можете сделать эти методы путем перекодирования, преобразования в матрицу, а затем преобразования в фрейм данных (аналогично приведенному ниже).
Другой вариант - dplyr::case_when
, который похож на векторизованный оператор switch
.Одним из преимуществ здесь является то, что, поскольку у вас есть несколько значений, заменяемых на 2, вы можете использовать %in%
вместо повторения.
as.data.frame(matrix(case_when(
df %in% c("Y", "yes", "always") ~ 2,
df == "Often" ~ 1,
T ~ 0
), nrow = 3, ncol = 3))
Наконец, dplyr::mutate_all
позволяет вам использовать recode
во всех столбцахпосле преобразования во фрейм данных.
mutate_all(as.data.frame(df), recode, !!!lookup, .default = 0)