You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数传入DataFrame时跨多列处理及按年龄组汇总非NA行数方案

问题描述

我有多个结构完全一致的DataFrame,想通过函数将每个输入的DataFrame按指定年龄组汇总个体级数据,生成每行对应一个年龄组的输出DataFrame,统计regularVar_names中各变量的非NA行数。

目前尝试的代码因无法正确传入DataFrame报错,具体信息如下:

数据示例

input.ds.2018 = data.frame(Var1 = c(1,1,NA,NA,1,2),Var2 = rep(c(1,2),3),V3 = c(NA,rep(2,4),1),
                         y_4 = c(NA,"y","z","l","m","n"),X_AGE80 = c(17,18,NA,84,21,72))

尝试的代码

calc_unwt_n_regularVar_fn = function(df,VAR){
  df %>% filter(!is.na(eval(parse(text = VAR)))) %>% nrow

}
# apply calc_unwt_n_regularVar_fn to age-group 18 to 84 for regular variables called Var1 and Var2
regularVar_names = c("Var1","Var2")
output = input.ds.2018 %>%
  filter(X_AGE80 <= 84) %>%
  filter(X_AGE80 >= 18)  %>%
  summarize(across(all_of(regularVar_names), ~ calc_unwt_n_regularVar_fn(.,cur_column()),.names = "unwt_denom_{.col}"))

报错信息

Error in `summarize()`:
i In argument: `across(...)`.
Caused by error in `across()`:
! Can't compute column `unwt_denom_Var1`.
Caused by error in `UseMethod()`:
! no applicable method for 'filter' applied to an object of class "c('double', 'numeric')" 

咨询两个问题:

  1. 如何将DataFrame作为参数传入自定义函数calc_unwt_n_regularVar_fn?
  2. 若当前思路不佳,如何优雅实现多DataFrame、多年龄组的汇总需求?

解答

问题1:正确传入DataFrame到自定义函数

报错根源是across调用函数时,传递的是单个列的向量而非整个DataFrame,针对这个问题有两种解决方式:

方式1:简化函数,直接处理向量

既然across传递的是列向量,函数无需处理整个DataFrame,直接统计非NA值数量即可:

calc_unwt_n_regularVar_fn = function(vec){
  sum(!is.na(vec))
}

调用时无需传列名,直接使用:

output = input.ds.2018 %>%
  filter(between(X_AGE80, 18, 84)) %>%
  summarize(across(all_of(regularVar_names), 
                   ~ calc_unwt_n_regularVar_fn(.),
                   .names = "unwt_denom_{.col}"))

方式2:传递完整DataFrame与列名

如果要保留原函数处理整个DataFrame的逻辑,需用cur_data()获取当前分组的完整数据,同时用.data[[VAR]]替代不安全的eval(parse(...)):

calc_unwt_n_regularVar_fn = function(df, VAR){
  df %>% filter(!is.na(.data[[VAR]])) %>% nrow()
}

output = input.ds.2018 %>%
  filter(between(X_AGE80, 18, 84)) %>%
  summarize(across(all_of(regularVar_names), 
                   ~ calc_unwt_n_regularVar_fn(cur_data(), cur_column()),
                   .names = "unwt_denom_{.col}"))

问题2:优雅实现多DataFrame、多年龄组的汇总

推荐用purrr结合分组操作批量处理,步骤如下:

步骤1:定义年龄组规则

将需要的年龄组整理为列表:

age_groups = list(
  "18-44" = c(18,44),
  "45-64" = c(45,64),
  "65-84" = c(65,84),
  "18-84" = c(18,84)
)

步骤2:编写通用汇总函数

输入单个DataFrame和年龄组范围,输出对应汇总结果:

summarize_by_age = function(df, age_min, age_max, var_names){
  df %>%
    filter(between(X_AGE80, age_min, age_max)) %>%
    summarize(
      age_group = paste0(age_min, "-", age_max),
      across(all_of(var_names), 
             ~ sum(!is.na(.)),
             .names = "unwt_denom_{.col}")
    )
}

步骤3:批量处理多DataFrame与年龄组

将所有待处理的DataFrame放入列表,用purrr::map_dfr批量生成并合并结果:

library(purrr)
library(dplyr)

# 假设还有2019、2020年的数据集
df_list = list(
  "2018" = input.ds.2018,
  "2019" = input.ds.2019,
  "2020" = input.ds.2020
)

all_results = map_dfr(df_list, function(df){
  map_dfr(age_groups, function(age_range){
    summarize_by_age(df, age_range[1], age_range[2], regularVar_names)
  })
}, .id = "year")

最终all_results会包含所有年份、所有年龄组的汇总数据,结构清晰便于后续分析。

内容的提问来源于stack exchange,提问作者abrar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:23:15