purrr::map结合count/mutate自定义函数批量统计变量频次的报错修复
批量统计数据框变量观测频次的实现问题
示例数据集
ï..Employee_Name PositionID Position State Zip 1: Adinolfi, Wilson K 19 Production Technician I MA 1960 2: Ait Sidi, Karthikeyan 27 Sr. DBA MA 2148 3: Akinkuolie, Sarah 20 Production Technician II MA 1810 4: Alagbe,Trina 19 Production Technician I MA 1886 5: Anderson, Carol 19 Production Technician I MA 2169 --- 307: Woodson, Jason 20 Production Technician II MA 1810 308: Ybarra, Catherine 19 Production Technician I MA 2458 309: Zamora, Jennifer 6 CIO MA 2067 310: Zhou, Julia 9 Data Analyst MA 2148 311: Zima, Colleen 19 Production Technician I MA 1730
已定义的自定义函数
函数作用为对数据框指定变量做观测值频次统计,按频次降序排列,并将变量值转换为按频次排序的有序因子:
HRdata_factor_count <- function(df, var) { df %>% count(.data[[var]], sort = T) %>% mutate(!!var := fct_reorder(factor(.data[[var]]), n)) }
第一次尝试与报错
希望通过purrr包的map函数批量调用自定义函数,遍历所有变量完成统计,执行代码如下:
map(HRdata, ~HRdata_factor_count(.x))
运行后触发报错:
Error in UseMethod("count") : no applicable method for 'count' applied to an object of class "character"
第二次尝试与异常输出
调整写法改用map2函数,执行代码:
HRnames <- names(HRdata) map2(HRdata, HRnames, ~HRdata_factor_count, df = .x, var =.y)
最终返回的列表内容为自定义函数的源码,而非预期的频次统计结果,输出片段如下:
$Position function(df, var) { df %>% count(.data[[var]], sort = T) %>% mutate(!!var := fct_reorder(factor(.data[[var]]), n)) } <bytecode: 0x000001e2ce372f60> $State function(df, var) { df %>% count(.data[[var]], sort = T) %>% mutate(!!var := fct_reorder(factor(.data[[var]]), n))
问题根源
- 第一次调用报错的核心原因:
map遍历数据框时,逐次传入的是每一列的独立向量,而非完整数据框,与自定义函数要求的df参数类型不匹配,导致count()方法无法识别输入对象类型。 - 第二次调用返回函数源码的核心原因:
map2的匿名函数写法错误,将函数实参写在了匿名函数表达式外部,本质上没有执行函数调用,仅将自定义函数对象本身存入了返回列表。
修正后的实现代码
自定义函数的统计逻辑本身不存在问题,只需调整批处理时的参数传递方式,保证每次循环都传入完整数据框、匹配对应列名即可达成目标。
运行前需确保已加载依赖包:library(dplyr)、library(purrr)、library(forcats)
# 方案1:遍历所有列名,逐次将完整数据框、列名传入函数 HR_names <- names(HRdata) freq_result <- map(HR_names, ~HRdata_factor_count(df = HRdata, var = .x)) # 为结果列表添加对应列名作为标签,方便后续调取 freq_result <- setNames(freq_result, HR_names)
# 方案2:使用map2匹配传入参数 # 第一个参数为重复的完整数据框,第二个参数为所有列名 freq_result <- map2( .x = rep(list(HRdata), times = ncol(HRdata)), .y = names(HRdata), .f = function(input_df, input_var) { HRdata_factor_count(df = input_df, var = input_var) } )
内容的提问来源于stack exchange,提问作者Taren Shaw
相关产品推荐
相关产品推荐

