使用dplyr的tally函数处理多列生成代码本
嘿,我明白你现在的困扰——手里有个百来个变量的 dataframe,想批量生成每个变量的频次表还能导出到 Excel,之前写的函数单独用没问题,但循环列名就卡壳了对吧?
问题出在你用 enquo() 处理变量的方式上:这个函数是用来捕获裸变量名(比如直接写 age 而不是 "age")的,但循环的时候你大概率是在遍历字符串形式的列名,enquo() 没法正确解析这些字符串,自然就跑不通了。
给你一套更适合批量处理的方案,分分钟搞定:
第一步:调整频次统计函数
先把函数改成接受字符串变量名的形式,用 .data[[var_name]] 来引用变量,这样不管是单独用还是批量循环都能兼容:
library(dplyr) freq_fun <- function(var_name) { raw %>% group_by(group, .data[[var_name]]) %>% tally(name = "频次") %>% # 给频次列起个明确的名字 rename(!!var_name := `.data[[var_name]]`) # 把统计列改回原变量名,看着更直观 }
第二步:批量生成所有变量的频次表
用 purrr 包的 map 函数来批量处理,比手动循环简洁多了:
library(purrr) library(writexl) # 先获取所有需要统计的变量名(排除分组变量group) target_vars <- setdiff(names(raw), "group") # 批量生成频次表,结果是一个列表,每个元素对应一个变量的统计结果 freq_results <- map(target_vars, freq_fun) # 给列表元素命名,这样导出到Excel时每个sheet就是变量名 names(freq_results) <- target_vars
第三步:导出到Excel
直接用 writexl 包的 write_xlsx 函数,就能把每个变量的频次表放到Excel的单独sheet里:
write_xlsx(freq_results, path = "变量频次代码本.xlsx")
额外优化:生成更完整的代码本
如果你想要的不只是频次,还想加入变量类型、缺失值统计这些代码本必备信息,可以扩展函数:
codebook_fun <- function(var_name) { var_data <- raw[[var_name]] # 生成变量基础信息 basic_info <- tibble( 变量名 = var_name, 变量类型 = paste(class(var_data), collapse = "/"), 缺失值数量 = sum(is.na(var_data)), 非缺失值数量 = sum(!is.na(var_data)) ) # 生成频次表(自动跳过缺失值) freq_table <- raw %>% filter(!is.na(.data[[var_name]])) %>% group_by(group, .data[[var_name]]) %>% tally(name = "频次") %>% mutate(分组占比 = 频次 / sum(频次)) %>% rename(!!var_name := `.data[[var_name]]`) # 返回包含基础信息和频次的列表 list(基础信息 = basic_info, 频次统计 = freq_table) } # 批量生成完整代码本 full_codebook <- map(target_vars, codebook_fun) names(full_codebook) <- target_vars # 再单独生成一份总览式的基础信息表,方便快速查看 total_overview <- map_dfr(target_vars, function(var) { var_data <- raw[[var]] tibble( 变量名 = var, 变量类型 = paste(class(var_data), collapse = "/"), 缺失值数量 = sum(is.na(var_data)), 非缺失值数量 = sum(!is.na(var_data)) ) }) # 把总览表和各变量详情合并后导出 export_content <- c(list(变量总览 = total_overview), full_codebook) write_xlsx(export_content, path = "完整变量代码本.xlsx")
这样导出的Excel里,第一个sheet是所有变量的基础信息总览,后面每个sheet对应一个变量的基础信息和频次统计,完美满足你的需求~
内容的提问来源于stack exchange,提问作者MokeEire
相关产品推荐
相关产品推荐

