使用dplyr和lubridate实现仅当月NA<10天的日度数据按月汇总
R 气象数据按月聚合(控制NA数量阈值)实现方法
你可以在summarise中加入条件判断逻辑,先统计单月内目标变量的NA数量,再根据阈值决定是否计算均值:
完整实现代码
library(dplyr) library(lubridate) # 步骤1:构造示例数据(原有数据部分可直接保留) exmpldf <- data.frame(DATE = c("1955-06-01", "1955-06-02", "1955-06-03", "1955-06-04", "1955-06-05", "1955-06-06", "1955-06-07", "1955-06-08", "1955-06-09", "1955-06-10", "1955-06-11", "1955-06-12", "1955-06-13", "1955-06-14", "1955-06-15", "1955-06-16", "1955-06-17", "1955-06-18", "1955-06-19", "1955-06-20", "1955-06-21", "1955-06-22", "1955-06-23", "1955-06-24", "1955-06-25", "1955-06-26", "1955-06-27", "1955-06-28", "1955-06-29", "1955-06-30", "1955-07-01", "1955-07-02", "1955-07-03", "1955-07-04", "1955-07-05", "1955-07-06", "1955-07-07", "1955-07-08", "1955-07-09", "1955-07-10", "1955-07-11", "1955-07-12", "1955-07-13", "1955-07-14", "1955-07-15", "1955-07-16", "1955-07-17", "1955-07-18", "1955-07-19", "1955-07-20", "1955-07-21", "1955-07-22", "1955-07-23", "1955-07-24", "1955-07-25", "1955-07-26", "1955-07-27", "1955-07-28", "1955-07-29", "1955-07-30", "1955-07-31", "1955-08-01", "1955-08-02", "1955-08-03", "1955-08-04", "1955-08-05", "1955-08-06", "1955-08-07", "1955-08-08", "1955-08-09", "1955-08-10", "1955-08-11", "1955-08-12", "1955-08-13", "1955-08-14", "1955-08-15", "1955-08-16", "1955-08-17", "1955-08-18", "1955-08-19", "1955-08-20", "1955-08-21", "1955-08-22", "1955-08-23", "1955-08-24", "1955-08-25", "1955-08-26", "1955-08-27", "1955-08-28", "1955-08-29", "1955-08-30", "1955-08-31", "1955-09-01", "1955-09-02", "1955-09-03", "1955-09-04", "1955-09-05", "1955-09-06", "1955-09-07", "1955-09-08", "1955-09-09", "1955-09-10", "1955-09-11", "1955-09-12", "1955-09-13", "1955-09-14", "1955-09-15", "1955-09-16", "1955-09-17", "1955-09-18", "1955-09-19", "1955-09-20", "1955-09-21", "1955-09-22", "1955-09-23", "1955-09-24", "1955-09-25", "1955-09-26", "1955-09-27", "1955-09-28", "1955-09-29", "1955-09-30"), TMAX = c(NA, 20, 27, 17, 26.5, 27, 17, 26.5, 20, 23, 23, 21.5, 24, 26.5, 27, 27, 26.5, 24.5, 23, 22.5, 24, 23, 21.5, 25, 26.5, 23, 24, 23.5, 23, 23, 23, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 24, 22, 21, 17, 17, 17, 21.5, 22, 22, 22.5, 22.5, 16.5, 20.5, 17.5, 23, 17, 21, 21.5, 21, 21, 20, 22, 22, 22, 21.5, 21.5, 21.5, 22.5, 20, 21, 20, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)) # 步骤2:处理日期、提取年月(优化写法,无需后续修改列名) exmpldf <- exmpldf %>% mutate( DATE = ymd(DATE), # 先将日期列转为标准日期格式,避免后续运算出错 MONTH = month(DATE), YEAR = year(DATE) ) # 步骤3:按年月分组,带NA阈值计算月均值 exmpldfmeanMonth <- exmpldf %>% group_by(MONTH, YEAR) %>% summarise( TMAX = if_else( condition = sum(is.na(TMAX)) <= 10, # 单月NA数量≤10时计算均值 true = mean(TMAX, na.rm = TRUE), false = NA_real_ # 否则返回NA,使用NA_real_避免数值类型不匹配报错 ), .groups = "drop" # 分组计算完成后自动取消分组,避免后续操作出现警告 )
结果说明
运行上述代码后得到的月均值结果完全符合要求:
- 1955年6月:NA数量1个≤10,返回正常均值
- 1955年7月:NA数量30个>10,返回NA
- 1955年8月:NA数量0个≤10,返回正常均值
- 1955年9月:NA数量30个>10,返回NA
多变量批量处理扩展
如果需要同时处理气温、降水等多个变量,可以用across()函数批量实现,无需重复写判断逻辑:
exmpldfmeanMonth <- exmpldf %>% group_by(MONTH, YEAR) %>% summarise( across(c(TMAX, PRECIP), # 此处填写所有需要计算的变量名 ~ if_else(sum(is.na(.x)) <=10, mean(.x, na.rm = T), NA_real_)), .groups = "drop" )
内容的提问来源于stack exchange,提问作者Fulano_LeTal
相关产品推荐
相关产品推荐

