函数内自动化生成.tex表格时dplyr均值计算报错的技术问询
解决dplyr聚合变量引用错误与stargazer表格均值添加问题
问题根源
你的代码存在两个核心错误,导致了警告和NA结果:
- 函数参数与变量引用不匹配:函数定义的参数是
y,但你在函数内部错误写了outcome = eval(i)——函数内部不存在i变量(i是循环外部的迭代变量),这会导致outcome值异常,后续引用列名时出错。 - dplyr中非标准求值误用:在
summarise里直接写mean(i, na.rm=T),dplyr会把i当成数据框的列名去查找,但你的数据框里没有名为i的列,因此触发「参数非数值型」警告,返回NA。
修正后的完整代码
reg_coef_tables <- function(df, y) { ### Function: Converts panel data to data usable for .tex tables # - df = panel data for the country # - y = outcome (fcs, fies, etc.) # - Full example: reg_pooled_lasso(df, "fcs") df <- df %>% filter(round_pooled != 0) # 直接使用传入的参数y作为结果列名(y是字符串格式) outcome <- y # 使用.data[[outcome]]引用字符串格式的列名,符合tidyverse规范 mean_outcome <- df %>% filter(round_pooled == 11 & treatment_arm == 0) %>% summarise(mean = mean(.data[[outcome]], na.rm = TRUE)) %>% pull(mean) # --- 后续代码保持不变 --- control <- paste0(outcome, "_imp") df <- df[complete.cases(df[, c(outcome, control)]),] vars <- df[complete.cases(df[, c(outcome, control, 'hhh_age_imp', 'sex_hhh_imp', 'hh_total_imp', 'hasplots_imp', 'hh_own_bus_imp', 'own_livestock_imp', 'tot_lstock_count_tlu_imp', 'wage_job_any_imp', 'hh_assets_tot_imp', 'farm_assets_tot_imp', 'round_cont', 'level1')]),] depvar <- data.matrix(vars[, outcome]) indepvars <- data.matrix(vars[, c('hhh_age_imp', 'sex_hhh_imp', 'hh_total_imp', 'hasplots_imp', 'hh_own_bus_imp', 'own_livestock_imp', 'tot_lstock_count_tlu_imp', 'wage_job_any_imp', 'hh_assets_tot_imp', 'farm_assets_tot_imp', 'round_cont', 'level1')]) model <- cv.glmnet(indepvars, depvar, alpha = 1, type.measure = "mse") c <- coef(model, s = "lambda.1se", exact = TRUE) inds <- which(c!=0) variables <- row.names(c)[inds] variables <- variables[!(variables %in% c('(Intercept)', 'round_cont', 'level1'))] controls <- paste0(variables, collapse = " + ") controls <- paste0("+ ", controls) control <- paste0("+ ", control) variables_all <- toString(variables) controls <- ifelse(variables_all == "", "", controls) reg1 <- felm(as.formula(paste(outcome, "~ treatment", " | level1 + round_cont | 0 | level4 + hhid")), data = df) reg2 <- felm(as.formula(paste(outcome, "~ treatment", control, " | level1 + round_cont | 0 | level4 + hhid")), data = df) reg3 <- felm(as.formula(paste(outcome, "~ treatment", controls, control, " | level1 + round_cont | 0 | level4 + hhid")), data = df) reg4 <- felm(as.formula(paste(outcome, "~ treat_uct + treat_ffa", " | level1 + round_cont | 0 | level4 + hhid")), data = df) reg5 <- felm(as.formula(paste(outcome, "~ treat_uct + treat_ffa", control, " | level1 + round_cont | 0 | level4 + hhid")), data = df) reg6 <- felm(as.formula(paste(outcome, "~ treat_uct + treat_ffa", controls, control, " | level1 + round_cont | 0 | level4 + hhid")), data = df) stargazer(reg1, reg2, reg3, reg4, reg5, reg6, align = TRUE, dep.var.labels = c("(1)", "(2)","(3)", "(4)", "(5)", "(6)"), omit.stat = c("f", "adj.rsq", "ser"), no.space = TRUE, digits = 3, add.lines = list(c('Mean outcome', rep(mean_outcome, 6)), c('Lasso controls', "No", "No", "Yes", "No", "No", "Yes"), c('County FE', rep("Yes", 6)), c('Month FE', rep("Yes", 6))), dep.var.caption = "", out = paste0(high_frequency_output_filepath, outcome, ".tex")) } # 简化循环写法,用lapply更简洁 liv_vars <- c("hasplots") liv_out_list <- lapply(liv_vars, function(i) reg_coef_tables(df, i))
关键修改说明
- 参数匹配修正:直接将函数参数
y赋值给outcome,循环中传入的i是字符串格式的列名,y会直接接收这个值,无需额外的eval操作。 - dplyr列名引用规范:使用
.data[[outcome]]引用字符串格式的列名,这是tidyverse官方推荐方式,避免非标准求值带来的变量混淆,确保dplyr能正确找到目标列计算均值。 - 循环简化:用
lapply替代手动创建list并赋值的写法,更符合R函数式编程风格,减少出错概率。
修改后,mean_outcome会正确计算指定列的均值,不再触发警告,且能正常显示在stargazer表格的add.lines区域中。
内容的提问来源于stack exchange,提问作者Paula
相关产品推荐
相关产品推荐

