R语言按行指定列数对年份对应temp列子集应用函数生成GDD列
R实现按行指定列数计算GDD的方案
最小改动方案(兼容原有循环逻辑)
只需要调整自定义函数和选择的列即可,改动量最小:
# 调整后的GDD计算函数,输入值第一个元素为meandoy,后续为当年按顺序排列的temp值 sum.GDD <- function(x) { k <- x[1] valid_temps <- x[-1][1:k] sum(valid_temps[valid_temps > 5] - 5, na.rm = TRUE) } yearlist <- c(1997, 1998) for (year in yearlist){ col_name <- paste0("GDD", year) df[[col_name]] <- df %>% # 先选meandoy列,再选对应年份的temp列(列默认按01/02/03/04顺序排列,符合需求) dplyr::select(meandoy, contains(as.character(year))) %>% apply(1, sum.GDD) }
运行后得到的结果完全符合要求:
- 第一行
meandoy=3:GDD1997=10,GDD1998=4 - 第二行
meandoy=2:GDD1997=5,GDD1998=5
扩展性更强的tidyverse长表方案
如果年份、月份数量多,推荐用长表转换的方式,不需要手动维护年份列表:
library(dplyr) library(tidyr) # 宽表转长表处理 df_gdd <- df %>% pivot_longer( cols = starts_with("temp"), names_to = c("year", "month"), names_pattern = "temp(\\d{4})(\\d{2})", names_transform = list(year = as.integer, month = as.integer) ) %>% # 仅保留meandoy指定数量的前N个月数据 filter(month <= meandoy) %>% group_by(id, year) %>% summarise(GDD = sum(value[value >5 ] -5, na.rm = TRUE), .groups = "drop") %>% # 长表转宽表匹配原数据结构 pivot_wider(names_from = year, values_from = GDD, names_prefix = "GDD") # 合并回原数据框 df <- left_join(df, df_gdd, by = "id")
内容的提问来源于stack exchange,提问作者Manuel Frias
相关产品推荐
相关产品推荐

