如何从分组数据帧中的每个组中获取第n个元素

时间:2019-07-16 23:08:56

标签: r dataframe filter dplyr grouping

我有一个大数据框,其中有一列,具有一个组名,该组名与 dplyr 分组。因此,多行具有相同的组名。为了减少数据,我想从每个组的第一个元素中提取第n个元素。有没有 R方式而没有循环?

用序列对每一行进行子集化,经常会丢失每个组的第一行。例如

<p>Somewhere!</p>

输入:

data[seq(1, nrow(data), 10), ] # Some groups start without the first row.

输出(第二个元素,请注意第三行!):

   Val Group
1  1.0 Fruit
2  2.0 Fruit
3  3.0 Fruit
4  1.5 Veg
5  2.8 Veg
6  4.2 Veg
7  5.1 Veg

4 个答案:

答案 0 :(得分:8)

library(dplyr)
data %>% group_by(Group) %>%
  slice(seq(1, n(), by = 2))

这给出了:

# A tibble: 4 x 2
# Groups:   Group [2]
    Val Group
  <dbl> <fct>
1   1   Fruit
2   3   Fruit
3   1.5 Veg  
4   4.2 Veg 

答案 1 :(得分:2)

这是基本的R方式:

DF$ID_by_Group <- ave(DF$Val, DF$Group, FUN =  seq_along)
DF[DF$ID_by_Group %in% seq(1,3, by = 2), ]

  Val Group ID_by_Group
1 1.0 Fruit           1
3 3.0 Fruit           3
4 1.5   Veg           1
6 4.2   Veg           3

ave()函数按组创建一个ID。第二条语句只是基于我们创建的ID_by_Group进行过滤。

请注意,我们可以一次完成所有操作和/或删除添加的列:

DF[ave(DF$Val, DF$Group, FUN =  seq_along) %in% seq(1,3, by = 2), ]

DF$ID_by_Group <- ave(DF$Val, DF$Group, FUN =  seq_along)

DF[DF$ID_by_Group %in% seq(1,3, by = 2), -3]
DF[DF$ID_by_Group %in% seq(1,3, by = 2), -grep('ID_by_Group', names(DF))]
DF[DF$ID_by_Group %in% seq(1,3, by = 2), c('Val', 'Group')]

#all provide:

  Val Group
1 1.0 Fruit
3 3.0 Fruit
4 1.5   Veg
6 4.2   Veg

答案 2 :(得分:0)

另一种选择是data.table

> setDT(data)                   
> data[(rowid(Group) %% 2) == 1]
   Val Group                    
1: 1.0 Fruit                    
2: 3.0 Fruit                    
3: 1.5   Veg                    
4: 4.2   Veg                    

答案 3 :(得分:0)

另一个基本R选项,可使用ave展开回收属性来选择每组中的第n行

n <- 2

df[as.logical(with(df, ave(Val, Group, FUN = function(x) 
                      c(TRUE, rep(FALSE, n - 1))))),  ]

#  Val Group
#1 1.0 Fruit
#3 3.0 Fruit
#4 1.5   Veg
#6 4.2   Veg

这将返回警告消息,因为返回的向量长度不同,但我认为可以忽略。

或者在评论中使用@thelatemail的想法,但不会给出警告消息。

df[as.logical(with(df, ave(Val, Group, FUN = function(x) 
                   seq_along(x) %% 2 == 1))), ]