#r #for-loop #variables #dynamic
Вопрос:
У меня возникли проблемы с созданием имен динамических переменных в цикле for. Я ссылался на предыдущие сообщения stackoverflow по этой теме, чей код я копирую, но он не работает в моих обстоятельствах. Я перекодирую ответы на опрос, чтобы учесть логику пропуска, и пытаюсь использовать следующий код для более эффективного перекодирования вместо одного за другим. Дайте мне знать, если у вас есть какие-либо предложения.
# Example data:
var0 = c(1, 2, 2, 1, 1, 2, 2)
var1 = c(NA, 1, 0, 1, 0, NA, 4444)
var2 = c(1, NA, 0, 0, 1, 4444, NA)
var3 = c(NA, 1, 0, 4444, 1, NA, 1)
df1 <- data.frame(var0, var1, var2, var3)
# Data:
var0 var1 var2 var3
1 1 NA 1 NA
2 2 1 NA 1
3 2 0 0 0
4 1 1 0 4444
5 1 0 1 1
6 2 NA 4444 0
7 2 4444 NA 1
Это моя функция и для цикла:
vars = c("var1", "var2")
func <- function(i) {
mutate(df1, !!i := case_when(!is.na(i) ~ i,
is.na(i) amp; var0 != '1' ~ '4444',
TRUE ~ '0'))
}
for(i in vars) {
df2 <- func(i)
}
test <- df2 %>%
select(var1, var3) #leaving var3 unchanged to test in comparison
Вот как я хотел бы, чтобы результат выглядел:
var0 var1 var2 var3
1 1 0 1 NA
2 2 1 4444 1
3 2 0 0 0
4 1 1 0 4444
5 1 0 1 1
6 2 4444 4444 NA
7 1 4444 0 1
Ответ №1:
Когда мы передаем строку, преобразуйте ее в sym
бол и оцените ( !!
)
func <- function(i) {
mutate(df1, !!i := case_when(!is.na(!! rlang::ensym(i)) ~ as.character(!! rlang::ensym(i)),
is.na(!!rlang::ensym(i)) amp; var0 != '1' ~ '4444',
TRUE ~ '0'))
}
-тестирование
for(i in vars) {
df1 <- func(i)
}
df1
var0 var1 var2 var3
1 1 0 1 NA
2 2 1 4444 1
3 2 0 0 0
4 1 1 0 4444
5 1 0 1 1
6 2 4444 4444 NA
7 2 4444 4444 1
Мы можем сделать это и с across
помощью
df1 %>%
mutate(across(all_of(vars),
~ case_when(!is.na(.) ~ as.character(.),
is.na(.) amp; var0 != '1' ~ '4444', TRUE ~ '0')))
var0 var1 var2 var3
1 1 0 1 NA
2 2 1 4444 1
3 2 0 0 0
4 1 1 0 4444
5 1 0 1 1
6 2 4444 4444 NA
7 2 4444 4444 1
Ответ №2:
Вы можете использовать .data
при передаче имени столбца в виде строки. Также обновите исходную переменную ( df1
) вместо создания новой ( df2
), потому что в функции вы всегда ссылаетесь на исходную переменную ( df1
).
library(dplyr)
func <- function(i) {
mutate(df1, !!i := case_when(!is.na(.data[[i]]) ~ .data[[i]],
is.na(.data[[i]]) amp; var0 != 1 ~ 4444,
TRUE ~ 0))
}
vars = c("var1", "var2")
for(i in vars) {
df1 <- func(i)
}
df1
# var0 var1 var2 var3
#1 1 0 1 NA
#2 2 1 4444 1
#3 2 0 0 0
#4 1 1 0 4444
#5 1 0 1 1
#6 2 4444 4444 NA
#7 2 4444 4444 1