使用dplyr在R数据框遍历列名按周汇总数据时遇错误求助
全球流行病日度数据转周度数据的问题解决
一、循环调用函数的报错修复
错误原因
- 循环逻辑错误:你用列索引
col去匹配列名向量id_cols,类型不匹配导致传入函数的列名可能是无需处理的标识列(如iso_code),触发!!sym(colName)的类型错误。 - 列名动态赋值错误:原函数中
colName = sum(...)不会将变量名作为列名,而是生成固定名为colName的列。 - 累计数据处理逻辑错误:
identity()在summarize中会返回整个组的向量,不符合summarize需要标量的要求,累计数据应取每周最后一天的数值。
修改后的代码
1. 修正处理函数
library(dplyr) library(purrr) # 新增类数据周度汇总(自动生成原列名) sumByColumn <- function(df, colName) { df %>% group_by(location, week) %>% summarize(!!colName := sum(!!sym(colName), na.rm = TRUE)) %>% ungroup() } # 累计类数据取每周最后一天的值(自动生成原列名) idByColumn <- function(df, colName) { df %>% group_by(location, week) %>% summarize(!!colName := last(!!sym(colName), na.rm = TRUE)) %>% ungroup() }
2. 批量处理替代循环
避免循环覆盖数据框,用purrr批量处理更高效:
# 定义列类型分组 id_cols <- c("total_cases", "total_deaths") # 累计类列名 sum_cols <- c("new_cases", "new_deaths") # 新增类列名 group_keys <- c("iso_code", "continent", "location", "week") # 提取每个国家-周的唯一标识信息 group_info <- df %>% group_by(location, week) %>% summarize(across(all_of(group_keys), first)) %>% ungroup() # 批量处理累计类数据 id_data <- map_dfc(id_cols, ~idByColumn(df, .x)) %>% select(-location, -week) # 去重复的分组列 # 批量处理新增类数据 sum_data <- map_dfc(sum_cols, ~sumByColumn(df, .x)) %>% select(-location, -week) # 去重复的分组列 # 合并所有数据得到周度结果 df_weekly <- bind_cols(group_info, id_data, sum_data)
二、处理无数据周与数据量不均问题
1. 生成完整的国家-周网格
先构建所有国家的完整周序列,确保没有缺失的时间节点:
library(lubridate) # 获取所有国家和所有周的范围 all_locations <- unique(df$location) all_weeks <- unique(df$week) %>% sort() # 生成所有国家-周的组合,并补充标识信息 full_grid <- expand.grid(location = all_locations, week = all_weeks, stringsAsFactors = FALSE) %>% left_join(df %>% select(location, iso_code, continent) %>% distinct(), by = "location") # 合并原始数据到完整网格 df_full <- full_grid %>% left_join(df, by = c("location", "week", "iso_code", "continent"))
2. 填充缺失值
根据数据类型填充合理值:
df_full_imputed <- df_full %>% group_by(location) %>% arrange(week) %>% # 新增类数据:缺失周填0(无新增病例/死亡) mutate(across(all_of(sum_cols), ~replace_na(.x, 0))) %>% # 累计类数据:用前一周的数值填充,初始无数据则设为0 mutate(across(all_of(id_cols), ~fill(.x, .direction = "down"))) %>% mutate(across(all_of(id_cols), ~replace_na(.x, 0))) %>% ungroup()
3. 基于填充后数据生成周度汇总
用前面的sumByColumn和idByColumn函数对填充后的完整数据处理,即可得到无NA、周数一致的周度数据集。
内容的提问来源于stack exchange,提问作者therickster
相关产品推荐
相关产品推荐

