用于在 for 循环中改变变量的动态变量名称
Dynamic variable names to mutate variables in for-loop
我在 for 循环中创建动态变量名时遇到问题。我参考了以前关于这个主题的 Whosebug 帖子,我正在复制谁的代码,但在我的情况下不起作用。我正在重新编码对调查的响应以考虑跳过逻辑,并尝试使用以下代码更有效地重新编码这些,而不是一个一个地重新编码。如果您有任何建议,请告诉我。
# 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
这是我的函数和 for 循环:
vars = c("var1", "var2")
func <- function(i) {
mutate(df1, !!i := case_when(!is.na(i) ~ i,
is.na(i) & 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
当我们传递字符串时,转换为 sym
bol 并计算 (!!
)
func <- function(i) {
mutate(df1, !!i := case_when(!is.na(!! rlang::ensym(i)) ~ as.character(!! rlang::ensym(i)),
is.na(!!rlang::ensym(i)) & 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(.) & 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
将列名作为字符串传递时,您可以使用 .data
。同时更新原始变量 (df1
) 而不是创建新变量 (df2
),因为在函数中您始终引用原始变量 (df1
).
library(dplyr)
func <- function(i) {
mutate(df1, !!i := case_when(!is.na(.data[[i]]) ~ .data[[i]],
is.na(.data[[i]]) & 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
我在 for 循环中创建动态变量名时遇到问题。我参考了以前关于这个主题的 Whosebug 帖子,我正在复制谁的代码,但在我的情况下不起作用。我正在重新编码对调查的响应以考虑跳过逻辑,并尝试使用以下代码更有效地重新编码这些,而不是一个一个地重新编码。如果您有任何建议,请告诉我。
# 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
这是我的函数和 for 循环:
vars = c("var1", "var2")
func <- function(i) {
mutate(df1, !!i := case_when(!is.na(i) ~ i,
is.na(i) & 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
当我们传递字符串时,转换为 sym
bol 并计算 (!!
)
func <- function(i) {
mutate(df1, !!i := case_when(!is.na(!! rlang::ensym(i)) ~ as.character(!! rlang::ensym(i)),
is.na(!!rlang::ensym(i)) & 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(.) & 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
将列名作为字符串传递时,您可以使用 .data
。同时更新原始变量 (df1
) 而不是创建新变量 (df2
),因为在函数中您始终引用原始变量 (df1
).
library(dplyr)
func <- function(i) {
mutate(df1, !!i := case_when(!is.na(.data[[i]]) ~ .data[[i]],
is.na(.data[[i]]) & 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