如何按组保留特定列中最低和最高值的行?

时间:2017-03-30 15:37:20

标签: r dplyr grouping

简而言之,我该怎么做呢

structure(list(id = c(1, 2, 3, 4, 5, 6), user = c(1, 1, 1, 2, 
2, 2), value = c(1, 3, 5, 2, 5, 9)), .Names = c("id", "user", 
"value"), row.names = c(NA, -6L), class = "data.frame")

到此?

structure(list(id = c(1, 3, 4, 6), user = c(1, 1, 2, 2), value = c(1, 
5, 2, 9)), .Names = c("id", "user", "value"), row.names = c(NA, 
-4L), class = "data.frame")

意思是,对于每个用户,只需要保留对应于最低和最高value的两行。

如果可能的话,我想使用dplyr的解决方案。否则,任何解决方案都可以。

2 个答案:

答案 0 :(得分:3)

在基数R中,我们可以将averange与这样的子集[结合起来

df1[as.logical(ave(df1$value, df1$user, FUN=function(i) i %in% range(i))), ]
  id user value
1  1    1     1
3  3    1     5
4  4    2     2
6  6    2     9

此处,%in%检查值的元素是否在range中,向量返回最小值和最大值,ave是否为每个用户应用此值。这将返回一个二进制(0,1)向量,其长度与data.frame的行数相同,后者将与as.logical转换为逻辑。如果您想要更短的内容,可以为as.logical更改!!

请注意,这将保留所有最小值和最大值,因此根据df$value的类型,这可能是也可能不合适。

答案 1 :(得分:2)

我们可以在用户'

分组后slicewhich.min/which.max一起使用
library(dplyr)
df1 %>%
   group_by(user) %>%
   slice(c(which.min(value), which.max(value)))
#   id  user value
#  <dbl> <dbl> <dbl>
#1     1     1     1
#2     3     1     5
#3     4     2     2
#4     6     2     9

或另一个选项是arrange slice。在按用户&#39;,arrange对&#39;值&#39;进行分组后以升序为每个用户&#39;和slice第一行和最后一行

df1 %>% 
     group_by(user) %>%
     arrange(value) %>% 
     slice(c(1, n()))

如果有min和/或max&#39;值&#39;并希望保留所有minmax行,并使用filter

df1 %>%
     group_by(user) %>% 
     filter(value %in% c(min(value), max(value)))