如何按国家计算到满足TRUE条件前的FALSE行数?
R语言实现按国家计算到下一个TRUE的剩余FALSE数量
给定如下data.frame,需要为每个国家的每一行创建新列years_until,表示该行到下一个出现TRUE的行之前,还有多少个FALSE:
data <- data.frame(year = c(2010, 2011, 2012, 2013, 2014, 2010, 2011, 2012, 2013, 2014, 2010, 2011, 2012, 2013, 2014, 2010, 2011, 2012, 2013, 2014, 2010, 2011, 2012, 2013, 2014), nation = c("USA", "USA", "USA", "USA", "USA", "UK", "UK", "UK", "UK", "UK", "BEL", "BEL", "BEL", "BEL", "BEL", "AUS", "AUS", "AUS", "AUS", "AUS", "MEX", "MEX", "MEX", "MEX", "MEX"), approved = c(TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE))
期望输出示例:
nation approved years_until USA TRUE 3 USA FALSE 2 USA FALSE 1 USA FALSE 0 USA TRUE NA UK TRUE 0 UK TRUE 2 UK FALSE 1 UK FALSE 0 UK TRUE NA BEL FALSE 1 BEL FALSE 0 BEL TRUE 0 BEL TRUE 0 BEL TRUE NA AUS FALSE 0 AUS TRUE 0 AUS TRUE 0 AUS TRUE 0 AUS TRUE NA MEX TRUE 0 MEX TRUE 2 MEX FALSE 1 MEX FALSE 0 MEX TRUE NA
作为R语言新手,尝试过cumsum()但无法实现倒计数效果,需要可行的解决方案。
解决方案:用dplyr按组倒序计算
推荐用dplyr包(属于tidyverse生态,新手友好),核心思路是按国家分组后倒序遍历数据,计算到下一个TRUE的剩余FALSE数量:
步骤1:安装并加载dplyr
如果还没安装包,先执行:
install.packages("dplyr") library(dplyr)
步骤2:编写计算逻辑
result <- data %>% # 按国家分组 group_by(nation) %>% # 倒序排列,从最后一行往第一行算 arrange(desc(year)) %>% mutate( # 标记每个以TRUE结尾的区块:倒序中每次遇到TRUE就开启新组 group_id = cumsum(approved), # 在每个区块内生成倒计数:组内序号反转后减1,正好对应需要的数值 years_until = rev(row_number()) - 1, # 原数据的最后一行(倒序后的第一行)设为NA years_until = ifelse(row_number() == n(), NA, years_until), # 连续的TRUE行,years_until设为0 years_until = ifelse(approved & lead(approved, default = FALSE), 0, years_until) ) %>% # 恢复原数据的年份顺序 arrange(year) %>% # 取消分组 ungroup() %>% # 筛选出和示例一致的列 select(nation, approved, years_until)
步骤3:查看结果
执行print(result)就能得到和示例完全匹配的输出。
逻辑拆解
- 分组倒序:按国家分组后倒序排列,把"找下一个TRUE"变成"找上一个TRUE",更方便计数。
- 区块标记:用
cumsum(approved)在倒序数据里划分区块,每个区块从当前TRUE向上延伸到上一个TRUE。 - 倒计数生成:每个区块内反转行号再减1,直接得到从目标TRUE往前的剩余FALSE数量。
- 特殊值处理:把每个国家的最后一行设为NA,连续的TRUE行设为0,贴合示例要求。
内容的提问来源于stack exchange,提问作者polisci89
相关产品推荐
相关产品推荐

