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

6

我有一个大的数据框,其中有一列是组名,使用dplyr进行了分组。因此,多行具有相同的组名。为了减少数据量,我想从每个组的第一个元素开始提取每个第n个元素。是否有任何不需要循环的R方式

对于使用序列子集化每一行的方法,通常会错过每个组的第一行。例如:

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

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

   Val Group
1  1.0 Fruit
2  3.0 Fruit
**3  1.5 Veg**
4  4.2 Veg
4个回答

12
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 

2
或者使用计数器 - dat %>% group_by(Group) %>% filter(row_number() %% 2 == 1),这在处理大数据时应该会更快一些。 - thelatemail

4

以下是基于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

3

另一种选择是使用 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                    

1

使用ave利用循环属性选择每组中的每第n行的另一个基本R选项

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))), ]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接