将分组数据过滤到分组发生更改的行

时间:2018-09-18 22:12:14

标签: r dplyr

使用这些数据(在dput()之下),其中IndIDII是一个分组列,其中每个MigStratFact都有Year的多个观测值。

> head(Dat)
  IndIDII Year MigStratFact
1 BHS_376 2015      MidDist
2 BHS_376 2016      MidDist
3 BHS_376 2017      MidDist
4 BHS_376 2018    ShortDist
5 BHS_378 2015      MidDist
6 BHS_378 2016    ShortDist

我想将Dat过滤到lead()的{​​{1}}值与当前值不匹配的行,并且还要保留当前字段。

使用下面的代码,对于每个MigStratFact,我可以过滤到IndIDII所在的行,但不确定如何也保留引用(即当前)行。

lead(MigStratFact) != MigStratFact

所需的解决方案将过滤到第3、4、5、6、8、9、11、12、15、16行。

非常感谢

Dat %>%
  group_by(IndIDII) %>% 
  filter(lead(MigStratFact) != MigStratFact) %>% 
  as.data.frame()

2 个答案:

答案 0 :(得分:3)

尝试更改为

Dat %>%
  group_by(IndIDII) %>% 
  filter(lead(MigStratFact) != MigStratFact | lag(MigStratFact) != MigStratFact)
#    IndIDII Year MigStratFact
# 1  BHS_376 2017      MidDist
# 2  BHS_376 2018    ShortDist
# 3  BHS_378 2015      MidDist
# 4  BHS_378 2016    ShortDist
# 5  BHS_391 2015    ShortDist
# 6  BHS_391 2016      MidDist
# 7  BHS_394 2017      MidDist
# 8  BHS_394 2018    ShortDist
# 9  BHS_395 2017      MidDist
# 10 BHS_395 2018    ShortDist

答案 1 :(得分:2)

@konvas的答案很难解答,但这是另一种解决方案。我接受了按索引而不是按逻辑进行过滤的挑战,但是我承认阅读起来有点困难。

Dat %>%
  group_by(IndIDII) %>% 
  filter(row_number() %in% c(a <-  which(lead(MigStratFact) != MigStratFact), a + 1))

# A tibble: 10 x 3
# Groups:   IndIDII [5]
   IndIDII Year  MigStratFact
   <chr>   <chr> <fct>       
 1 BHS_376 2017  MidDist     
 2 BHS_376 2018  ShortDist   
 3 BHS_378 2015  MidDist     
 4 BHS_378 2016  ShortDist   
 5 BHS_391 2015  ShortDist   
 6 BHS_391 2016  MidDist     
 7 BHS_394 2017  MidDist     
 8 BHS_394 2018  ShortDist   
 9 BHS_395 2017  MidDist     
10 BHS_395 2018  ShortDist