R 分组变量保持序列的滤波

R 分组变量保持序列的滤波,r,dplyr,data.table,R,Dplyr,Data.table,我有一个数据帧: df <- data.frame( Group=c('A','A','A','A','B','B','B','B'), Activity = c('EOSP','NOR','EOSP','COSP','NOR','EOSP','WL','NOR'), TimeLine=c(1,2,3,4,1,2,3,4) ) 结果: # A tibble: 6 x 3 # Groups: Group [2] Group

我有一个数据帧:

df <- data.frame(
        Group=c('A','A','A','A','B','B','B','B'),
        Activity = c('EOSP','NOR','EOSP','COSP','NOR','EOSP','WL','NOR'),
        TimeLine=c(1,2,3,4,1,2,3,4)
      )
结果:

# A tibble: 6 x 3
# Groups:   Group [2]
  Group Activity TimeLine
  <fct> <fct>       <dbl>
1 A     EOSP            1
2 A     NOR             2
3 A     EOSP            3
4 B     NOR             1
5 B     EOSP            2
6 B     NOR             4
#一个tible:6 x 3
#分组:分组[2]
团体活动时间表
1 A EOSP 1
2 A或2
3 A EOSP 3
4 B或1
5 B EOSP 2
6 B或4

我不希望第3行出现在
之后,因为
EOSP
出现在
之后。同样,对于B组,我不想要第4行,因为
发生在
EOSP
之前。如何实现这一点?

您可以使用
match
获取
Activity==EOSP
的第一个实例,并使用
slice
删除之前的所有内容。一旦这样做,您就可以删除重复项并在
EOSP
上进行过滤,即

library(tidyverse)

df %>% 
 group_by(Group) %>% 
 mutate(new = match('EOSP', Activity)) %>% 
 slice(new:n()) %>% 
 distinct(Activity, .keep_all = TRUE) %>% 
 filter(Activity %in% c('EOSP', 'NOR'))
这就给了,

#一个tible:4 x 4
#分组:分组[2]
团体活动时间表新增
1 A EOSP 1 1
2 A或2 1
3 B EOSP 2
4 B或4 2
注意1:您可以
取消分组()
选择(-new)

注2:此处发出的警告消息

(警告信息: 1:在new:4L:数值表达式中有4个元素:仅使用第一个元素 2:在new:4L中:数值表达式有4个元素:仅使用第一个元素 )

不要影响我们,因为我们只需要它来使用第一个元素,因为所有元素都是相同的

这里有一个包选项:您将
df
与自身连接,将其子集,以仅保留
EOSP
活动
并按组计算
时间线的最小值,然后,您可以仅保留
时间线
大于或等于此
时间线
的行,以确保仅在之前存在
EOSP
时才保留
。如果希望每个组只保留2个活动,则删除重复的组和活动:

df[df[Activity=="EOSP", min(TimeLine), by=Group], on="Group"][Activity %in% c("NOR", "EOSP") & TimeLine >= V1][!duplicated(paste(Group, Activity))]

#   Group Activity TimeLine V1
#1:     A     EOSP        1  1
#2:     A      NOR        2  1
#3:     B     EOSP        2  2
#4:     B      NOR        4  2

下面是一个
dplyr
想法:

df %>%
  filter(Activity %in% c('EOSP','NOR')) %>%
  group_by(Group) %>%
  mutate(tmp = which(Activity == 'EOSP' & !duplicated(Activity))) %>%
  filter(row_number() %in%  c(tmp, tmp+1)) 

# A tibble: 4 x 4
# Groups:   Group [2]
  Group Activity TimeLine   tmp
  <fct> <fct>       <dbl> <int>
1 A     EOSP            1     1
2 A     NOR             2     1
3 B     EOSP            2     2
4 B     NOR             4     2
df%>%
筛选器(%c('EOSP','NOR')中的活动%)%>%
分组依据(分组)%>%
突变(tmp=which(Activity='EOSP'&!duplicated(Activity)))%>%
过滤器(行号()%在%c中(tmp,tmp+1))
#一个tibble:4x4
#分组:分组[2]
团体活动时间表
1 A EOSP 1 1
2 A或2 1
3 B EOSP 2
4 B或4 2

如果有多个
'EOSP'
'NOR'
按所需顺序排列,该怎么办。你也想保留它们吗?@RonakShah,是的,因为每个团体可能有多个这样的活动。基本上,这些活动都有时间戳,我试图计算它们之间的时间差。谢谢你今天两次帮助我!为什么不直接添加
…%>%您的代码中是否有不同的(活动)
?i、 e.
df%>%groupby(group)%%>%filter(全部(c('EOSP','NOR')%in%Activity)和活动%in%c('EOSP','NOR'))%%>%distinct(Activity)
@Sotos,不完全相同。这仍然不能维持我需要数据的顺序。使用您的代码,对于B组,我获得与时间线1和2对应的B组的值
NOR
EOSP
。但是,我需要与时间线活动2和4对应的
EOSP
NOR
。此外,同一组中可能有多对这样的活动。@Dhiraj也许您应该删除“也按时间线中指定的顺序”,因为您的顺序不是由B组中的时间线决定的。这太棒了!在我的原始数据中做了一个小的更改,有时活动
EOSP
在特定组中不存在,导致NAs。因此,就在您的
切片(new:n())
之前,添加了一个
na.omit()%%>%%
df[df[Activity=="EOSP", min(TimeLine), by=Group], on="Group"][Activity %in% c("NOR", "EOSP") & TimeLine >= V1][!duplicated(paste(Group, Activity))]

#   Group Activity TimeLine V1
#1:     A     EOSP        1  1
#2:     A      NOR        2  1
#3:     B     EOSP        2  2
#4:     B      NOR        4  2
df %>%
  filter(Activity %in% c('EOSP','NOR')) %>%
  group_by(Group) %>%
  mutate(tmp = which(Activity == 'EOSP' & !duplicated(Activity))) %>%
  filter(row_number() %in%  c(tmp, tmp+1)) 

# A tibble: 4 x 4
# Groups:   Group [2]
  Group Activity TimeLine   tmp
  <fct> <fct>       <dbl> <int>
1 A     EOSP            1     1
2 A     NOR             2     1
3 B     EOSP            2     2
4 B     NOR             4     2