我有一个包含许多变量的数据集,其中一些是字符变量,我想将其转换为因子。由于要转换的变量很多,我想使用dplyr_0.7
中新的整理评估功能来实现这一点。以下是我的数据中的一个最小示例:
data <- data.frame(factor1 = c("K", "V"),
factor2 = c("E", "K"),
other_var = 1:2,
stringsAsFactors = FALSE)
我有一个命名列表,其中包含我要转换的每个变量的data.frame
。列表中的这些data.frame
都具有相同的结构,可以在此示例中看到:
codelist_list <- list(factor1 = data.frame(Code = c("K", "V"),
Bezeichnung = c("Kauf", "Verkauf"),
stringsAsFactors = FALSE),
factor2 = data.frame(Code = c("E", "K"),
Bezeichnung = c("Eigengeschaeft", "Kundengeschaeft"),
stringsAsFactors = FALSE))
我做不想要做的是为每个变量定义这样的因素:
mutate(df, factor1 = factor(factor1,
levels = codelist_list[["factor1"]][["Code"]],
labels = codelist_list[["factor1"]][["Bezeichnung"]]))
到目前为止我所尝试的是以下内容:
convert_factors <- function(variable, df) {
factor_variable <- enquo(variable)
df %>%
mutate(!!quo_name(factor_variable) := factor(!!quo_name(factor_variable),
levels = codelist_list[[variable]][["Code"]],
labels = codelist_list[[variable]][["Bezeichnung"]]))
}
在第一步中,我想通过调用返回的convert_factors()
检查我的函数convert_factors("factor1", data)
是否正常工作
factor1 factor2 other_var
1 <NA> E 1
2 <NA> K 2
变量不显示值标签,而是替换为NA
。
最终目标是map
超过我要转换的所有变量。在这里,我尝试了map(c("factor1", "factor2"), convert_factors, df = data)
,它返回了
错误(函数(x,严格= TRUE):参数已被评估
我尝试按照http://dplyr.tidyverse.org/articles/programming.html的说明进行操作,但这就是我提出的所有内容。
有谁知道问题所在(并希望向我解释我的错误)。
答案 0 :(得分:3)
我认为你混淆了语录和字符串:
在你的功能中,variable
是一个字符串,而不是表达式。因此,您应该使用rlang::sym
而不是enquo
将其转换为现状。
quo_name
用于将表达式转换为字符串。由于variable
已经是一个字符串,您可以直接在!!variable
的rhs(右侧)上mutate
进行操作。
在mutate
的lhs中,您需要使用factor_variable
取消!!
而不是尝试将其转换为quo_name
的字符串。
在纠正上述错误后,您的功能将起作用:
convert_factors <- function(variable, df) {
factor_variable <- rlang::sym(variable)
df %>%
mutate(!!variable := factor(
!!factor_variable,
levels = codelist_list[[variable]][["Code"]],
labels = codelist_list[[variable]][["Bezeichnung"]]))
}
# > convert_factors('factor1', data)
# factor1 factor2 other_var
# 1 Kauf E 1
# 2 Verkauf K 2
以下是我的尝试:
params <- lapply(codelist_list, setNames, nm = c('levels', 'labels'))
convert_factors <- function(variable, df) {
factor_variable <- rlang::sym(variable)
factor_param <- c(list(factor_variable), params[[variable]])
df %>% mutate(!!variable := do.call(factor, factor_param))
}
convert_factors('factor1', data)
# factor1 factor2 other_var
# 1 Kauf E 1
# 2 Verkauf K 2
答案 1 :(得分:2)
使用整齐的eval和dplyr的mt1022的很好的解决方案。但是,这项任务只能通过base-R完成:
data[,names(codelist_list)] <- lapply(names(codelist_list), function(x)
data[,x] <- factor(data[,x],
levels = codelist_list[[x]][["Code"]],
labels = codelist_list[[x]][["Bezeichnung"]]))
答案 2 :(得分:1)
您可以使用mutate_at
使用.
内的funs
编码来处理此问题,以便立即将函数应用于多个列。
这种方法仍然需要使用tidyeval
从codelist_list
中提取正确的列表,同时通过.
引用变量。
mutate_at(data, c("factor1", "factor2"),
funs( factor(., levels = codelist_list[[quo_name(quo(.))]][["Code"]],
labels = codelist_list[[quo_name(quo(.))]][["Bezeichnung"]]) ) )
factor1 factor2 other_var
1 Kauf Eigengeschaeft 1
2 Verkauf Kundengeschaeft 2
如果你想让一个函数传递给mutate_at
,你可以这样做,只需稍作修改。
convert_factors = function(variable) {
var2 = enquo(variable)
factor(variable, levels = codelist_list[[quo_name(var2)]][["Code"]],
labels = codelist_list[[quo_name(var2)]][["Bezeichnung"]])
}
mutate_at(data, c("factor1", "factor2"), convert_factors)
factor1 factor2 other_var
1 Kauf Eigengeschaeft 1
2 Verkauf Kundengeschaeft 2
答案 3 :(得分:0)
由于您只是使用字符串和SE函数(因子构造函数),因此您不需要表达式或定义。只需对:=
convert_factors <- function(variable, df) {
factor <- factor(variable,
levels = codelist_list[[variable]][["Code"]],
labels = codelist_list[[variable]][["Bezeichnung"]]
)
mutate(df, !! variable := factor)
}
map(c("factor1", "factor2"), convert_factors, df = data)