如何用R语言tidyverse/dplyr统计数据框中连续TRUE值的数量
使用tidyverse统计连续TRUE值的计数
示例数据
首先定义示例数据框:
dftmp <- data.frame(order = 1:10, true = c(FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE))
初始数据形态:
order true 1 1 FALSE 2 2 TRUE 3 3 TRUE 4 4 TRUE 5 5 FALSE 6 6 FALSE 7 7 TRUE 8 8 FALSE 9 9 TRUE 10 10 TRUE
需求是添加count列,统计连续TRUE的数量(FALSE对应0),期望结果:
order true count 1 1 FALSE 0 2 2 TRUE 1 3 3 TRUE 2 4 4 TRUE 3 5 5 FALSE 0 6 6 FALSE 0 7 7 TRUE 1 8 8 FALSE 0 9 9 TRUE 1 10 10 TRUE 2
tidyverse实现方案
方法1:dplyr分组计数
核心思路是先将连续的相同true值归为一组,再在组内对TRUE行进行序号计数,FALSE行直接设为0:
library(dplyr) dftmp_result <- dftmp %>% # 创建分组标识:每次true值变化时,分组ID加1 mutate(group_id = cumsum(lag(true, default = FALSE) != true)) %>% # 按分组ID分组,计算count group_by(group_id) %>% mutate(count = ifelse(true, row_number(), 0)) %>% # 取消分组 ungroup() %>% # 移除临时分组列 select(-group_id)
方法2:purrr累积计算(贴合原循环逻辑)
如果想和你原来的循环逻辑更贴近,可以用purrr的accumulate()函数做累积运算,逐行计算count值:
library(dplyr) library(purrr) dftmp_result <- dftmp %>% mutate(count = accumulate(true, .init = 0, ~ ifelse(.y, .x + 1, 0))[-1])
解释:accumulate()会依次遍历true列的每个值,.init = 0是初始值(对应第0行的count);每次迭代时,若当前行true为TRUE(.y),就用上一次结果(.x)加1,否则设为0;最后去掉初始的.init值,得到和循环完全一致的结果。
内容的提问来源于stack exchange,提问作者awesome6uy
相关产品推荐
相关产品推荐

