R中基于df2双列计算df1对应plot指定日期前degree_days累计和的方法
实现逻辑修正
你写的循环没得到正确结果,核心问题是筛选df1临时子集时,只判断了日期大小关系,没有匹配当前行对应的plot编号,最终计算的是所有plot在目标日期前的总积温,不符合需求。
原循环最小改动版本
直接在原逻辑基础上补上plot匹配条件即可:
# 先确保两表的日期列是可比较的日期格式,不是文本 df1$date <- as.Date(df1$date, format = "%m-%d-%y") df2$mean_first_flower_date <- as.Date(df2$mean_first_flower_date, format = "%m-%d-%y") for (i in 1:nrow(df2)) { flower <- df2[i, "mean_first_flower_date"] current_plot <- df2[i, "plot"] # 提取当前行对应的plot print(i) # 筛选条件同时满足:同plot、日期<=初花日期 df1.temporary <- df1[df1$date <= flower & df1$plot == current_plot, ] new_var <- sum(df1.temporary$degree_days) df2[i, "new_var"] <- new_var }
小提示:如果不把文本格式的日期转成Date类,R会按字符串顺序比较大小,比如"5-16-19"会被判定为比"8-5-19"小,结果出错。
无循环的高效实现
循环在数据量较大时运行效率低,下面两种常用方案可以替代循环,运行速度更快:
dplyr 方案
library(dplyr) # 先按plot分组,计算每个plot从记录起始日到各日期的累计积温 df1_cum <- df1 %>% group_by(plot) %>% arrange(date, .by_group = TRUE) %>% mutate(cum_days = cumsum(degree_days)) %>% ungroup() # 逐行匹配对应累计值 df2 <- df2 %>% rowwise() %>% mutate( new_var = max( df1_cum$cum_days[df1_cum$plot == plot & df1_cum$date <= mean_first_flower_date], na.rm = TRUE ) ) %>% ungroup()
data.table 方案(适合十万行以上的大数据集)
library(data.table) setDT(df1) setDT(df2) # 按plot分组计算累计积温 df1[, cum_days := cumsum(degree_days), by = plot] # 按plot、小于等于目标日期的最近日期匹配累计值 df2[df1, on = .(plot, mean_first_flower_date = date), new_var := cum_days, roll = Inf]
按示例数据计算,plot1对应5月16日初花的累计值为3.5+4.5+3.5+4.5=16,和预期结果完全一致。
内容的提问来源于stack exchange,提问作者user3508884
相关产品推荐
相关产品推荐

