dplyr - r - 按分组返回长度

我想在下面的数据框中添加一个新列,计算每个月的最大干旱长度。这就是我的数据框架的外观:


 day month year rr spell spell1


 1 1 1981 0 dry 1


 2 1 1981 0 dry 1


 3 1 1981 0 dry 1


 4 1 1981 1.1 dry 0


 5 1 1981 0 dry 1


 6 1 1981 0 dry 1


 7 1 1981 0 dry 1


 8 1 1981 0 dry 1


 9 1 1981 2.7 dry 0


 10 1 1981 0 dry 1



这是我需要的输出:


 month year spell_length


 1 1981 3


 1 1981 4


 1 1981 1



这是我到目前为止所做的:


group_by(df, year, month, spell1) %>% 


 summarise(spell2 = sum(spell1, na.rm = TRUE))



这就是结果:


 year month spell1 spell_length


 <int> <int> <dbl> <dbl>


1 1981 1 1 31


2 1981 2 0 0


3 1981 2 1 27


4 1981 3 0 0


5 1981 3 1 25


6 1981 4 0 0



数据


df <- read.table(h= T, text="day month year rr spell spell1


1 1 1981 0 dry 1


2 1 1981 0 dry 1


3 1 1981 0 dry 1


4 1 1981 1.1 dry 0


5 1 1981 0 dry 1


6 1 1981 0 dry 1


7 1 1981 0 dry 1


8 1 1981 0 dry 1


9 1 1981 2.7 dry 0


10 1 1981 0 dry 1")



时间:

使用@akrun的基本思想,但是,不使用data.table::rleid()


df %>%


 group_by(year, month, rleid = with(rle(spell1), rep(seq_along(lengths), lengths))) %>%


 filter(spell1 > 0) %>%


 ungroup() %>%


 count(month, year, rleid, name = "spell_length") %>%


 select(-rleid) 



 month year spell_length


 <int> <int> <int>


1 1 1981 3


2 1 1981 4


3 1 1981 1



或者:


df %>%


 group_by(year, month, rleid = with(rle(spell1), rep(seq_along(lengths), lengths))) %>%


 filter(spell1 > 0) %>%


 summarise(spell_length = length(rleid)) %>%


 ungroup() %>%


 select(-rleid)



一个选项是通过'spell '的'run-length-id '进行分组(来自data.table的rleid - 当该列中的值发生变化时创建一个新的分组ID) ,过滤掉'spell1 '的行为0,用n()获取行数,


library(dplyr)


library(data.table)


df1 %>%


 group_by(year, month, grp = rleid(spell1)) %>%


 filter(spell1 ==1) %>%


 summarise(spell_length = n()) %>%


 ungroup %>%


 select(-grp)


# A tibble: 3 x 3


# year month spell_length


# <int> <int> <int>


#1 1981 1 3


#2 1981 1 4


#3 1981 1 1



或从base R使用rle


rl1 <- rle(df1$spell1)


rl1$lengths[rl1$values > 0]


#[1] 3 4 1



注意:当'spell1 '值不同时,此解决方案也有效,

使用dplyr,我们可以在每个0的每个出现都使用cumsum和每个组的spells数来创建组。


library(dplyr)



df %>%


 group_by(month, year, group = cumsum(spell1 == 0)) %>%


 summarise(spell_length = sum(spell1)) %>%


 ungroup() %>%


 select(-group)



# month year spell_length


# <int> <int> <int>


#1 1 1981 3


#2 1 1981 4


#3 1 1981 1



下面是使用dplyr::count的选项:


library(dplyr)


count(df, month, year, grp = cumsum(spell1 == 0), zero = spell1==0) %>%


 filter(!zero) %>%


 select(-zero, - grp)



# # A tibble: 3 x 3


# month year n


# <int> <int> <int>


# 1 1 1981 3


# 2 1 1981 4


# 3 1 1981 1



...