分组条件分组

时间:2019-09-12 20:00:58

标签: r

示例数据:

mydf<-data.frame(Group_ID=c("337", "337", "201", "201", "470", "470", "999", "999"), 
                              Timestamp=c("A", "A", "B", "B", "C", "D", "E", "F"), 
                              MU=as.numeric(c("1", "1", "2", "3", "4", "4", "5", "6")))

礼物:

    Group_ID Timestamp MU
         337         A  1
         337         A  1
         201         B  2
         201         B  3
         470         C  4
         470         D  4
         999         E  5
         999         F  6

如果MU大于1,我只想保留Group_ID中的第一个条目。如果MU <= 1,我想保留该组的所有条目。因此,

所需结果:

    Group_ID Timestamp MU
         337         A  1
         337         A  1
         201         B  2
         470         C  4
         999         E  5

我做了很多尝试,最接近的是以下示例。但是,此解决方案是错误的,因为它排除了MU <= 1的所有条目。

最佳尝试:

mydf <- mydf[(mydf$MU >= 1),] %>%            
  group_by(Group_ID) %>% 
  slice(1:1)  

返回不想要的结果(所有MU <= 1被排除而不是保留):

Group_ID Timestamp    MU
     201         B     2
     337         A     1
     470         C     4
     999         E     5

我很惊讶这种尝试不起作用,它缺少了什么?我也尝试过ifelse语句。提前非常感谢

4 个答案:

答案 0 :(得分:4)

mydf %>%
    group_by(Group_ID) %>%
    filter(cumsum(MU > 1) <= 1) %>%
    ungroup()
## A tibble: 5 x 3
#  Group_ID Timestamp    MU
#  <fct>    <fct>     <dbl>
#1 337      A             1
#2 337      A             1
#3 201      B             2
#4 470      C             4
#5 999      E             5

等效于R的

mydf[with(mydf, ave(MU > 1, Group_ID, FUN = cumsum) <= 1),]

答案 1 :(得分:1)

您可以在切片中使用which来选择所需的行索引。

编辑:当同一组中有MU <= 1的行和MU> 1的行时,我不知道该怎么办。该答案使该组的MU <= 1行,而第一个MU> 1行。

mydf %>% 
  group_by(Group_ID) %>% 
  slice(c(which(MU <= 1), head(which(MU > 1), 1)))

# # A tibble: 5 x 3
# # Groups:   Group_ID [4]
#   Group_ID Timestamp    MU
#   <fct>    <fct>     <dbl>
# 1 201      B             2
# 2 337      A             1
# 3 337      A             1
# 4 470      C             4
# 5 999      E             5

答案 2 :(得分:1)

我们可以根据'MU'中是否有slice元素大于1来按'Group_ID'和any进行分组

library(dplyr)
mydf %>% 
  group_by(Group_ID = factor(Group_ID, levels = unique(Group_ID))) %>%
  slice(if(any(MU> 1)) 1 else row_number() )
# A tibble: 5 x 3
# Groups:   Group_ID [4]
#  Group_ID Timestamp    MU
#  <fct>    <fct>     <dbl>
#1 337      A             1
#2 337      A             1
#3 201      B             2
#4 470      C             4
#5 999      E             5

答案 3 :(得分:0)

这应该为您工作。它增加了几行,因此虽然不够简洁,但仍然快速简便。

mydf1 <- mydf[(mydf$MU > 1),] %>%            
    group_by(Group_ID) %>% 
    slice(1:1)  
mydf2 <- rbind(mydf[(mydf$MU <= 1),],as.data.frame(mydf1))
mydf2