R语言如何按国家生成优先取第5年值、无值取近5年最近值的NewVar变量
R语言实现NewVar变量计算
根据你提供的示例数据的预期输出,对齐计算规则如下:
仅年份为5的整数倍的行需要填充
NewVar,其余行保持空值;按国家分组后,对符合年份要求的行,优先取对应年份的Data值,若该值为空则取该国家当前年份之前最近的非空Data值。
方案1:tidyverse实现(仅依赖dplyr)
library(dplyr) df2 <- df2 %>% group_by(Country) %>% arrange(Year) %>% mutate( # 生成分组标记:每遇到非空Data就新增一个分组 grp = cumsum(!is.na(Data)), # 每个分组内共享最近的非空Data值 last_valid_Data = Data[!is.na(Data)][grp], # 仅给5的倍数年份的行赋值 NewVar = ifelse(Year %% 5 == 0, last_valid_Data, NA_real_) ) %>% # 移除临时计算列 select(-grp, -last_valid_Data) %>% ungroup()
逻辑说明
- 按国家拆分数据组后按年份升序排列,保证时间顺序正确
- 用
cumsum生成分组标记,所有位于两个非空Data值之间的行归属同一个分组,共享前一个非空值 - 仅对年份为5的倍数的行赋值,其余行保留空值,完全匹配你给出的示例结果。
方案2:base R实现(无需安装第三方包)
# 先按国家、年份升序排序 df2 <- df2[order(df2$Country, df2$Year), ] # 按国家分组计算每行对应的最近非空Data值 df2$last_valid <- ave(df2$Data, df2$Country, FUN = function(x) { non_na_pos <- which(!is.na(x)) grp <- findInterval(seq_along(x), non_na_pos) x[non_na_pos][grp] }) # 仅给5的倍数年份的行赋值NewVar df2$NewVar <- ifelse(df2$Year %% 5 == 0, df2$last_valid, NA_real_) # 删除临时计算列 df2$last_valid <- NULL
内容的提问来源于stack exchange,提问作者Jens
相关产品推荐
相关产品推荐

