如何从dplyr数据框中的每个组中选择最后N个观测值?

时间:2019-01-01 09:53:20

标签: r dplyr

给出一个数据框:

cpanel.example.pe

我想从每组中获取最后N个观察值/行:

data Stmt
  = Var := Exp                                   
  | While Exp Stmt                                               
  | Seq [Stmt]      
  | Print Exp       -- a print statement

给我错误的结果。

我希望它是

df <- structure(list(a = c(1, 1, 1, 2, 2, 2, 3, 3, 4, 4), b = c(34, 
343, 54, 11, 55, 62, 59, -9, 0, -0.5)), row.names = c(NA, -10L
), class = c("tbl_df", "tbl", "data.frame"))

请告知这里有什么问题吗?

我得到的错误是:

  

order(order_by)[[n]]错误:下标超出范围

4 个答案:

答案 0 :(得分:5)

这是一个基于dplyr

的特定问题

1 )之后,在group_by

上使用slice
row_number()

2 )或使用library(tidyverse) df %>% group_by(a) %>% slice(tail(row_number(), 2)) # A tibble: 8 x 2 # Groups: a [4] # a b # <dbl> <dbl> #1 1 343 #2 1 54 #3 2 55 #4 2 62 #5 3 59 #6 3 -9 #7 4 0 #8 4 -0.5 中的filter

dplyr

3 )或使用df %>% group_by(a) %>% filter(row_number() >= (n() - 1)) do

tail

4 ),除了df %>% group_by(a) %>% do(tail(., 2)) 方法之外,我们还可以使用紧凑型tidyverse

data.table

5 )或library(data.table) setDT(df)[df[, .I[tail(seq_len(.N), 2)], a]$V1] 中的by

base R

6 )或使用by(df, df$a, FUN = tail, 2) 中的aggregate

base R

7 )或使用df[aggregate(c ~ a, transform(df, c = seq_len(nrow(df))), FUN = tail, 2)$c,] 中的split

base R

答案 1 :(得分:1)

还有tidyverse的可能性:

df %>%
 group_by(a) %>%
 top_n(2, row_number())

      a        b
  <dbl>    <dbl>
1    1.  343.   
2    1.   54.0  
3    2.   55.0  
4    2.   62.0  
5    3.   59.0  
6    3.   -9.00 
7    4.    0.   
8    4.   -0.500

给定每组的行号,它将占据前两行。

答案 2 :(得分:1)

使用tapply的基本R选项是对每个组的最后两行进行子集化。

df[unlist(tapply(1:nrow(df), df$a, tail, 2)), ]

#     a      b
#  <dbl>  <dbl>
#1     1  343  
#2     1   54  
#3     2   55  
#4     2   62  
#5     3   59  
#6     3   -9  
#7     4    0  
#8     4   -0.5

或使用ave

的另一个选项
df[as.logical(with(df, ave(1:nrow(df), a, FUN = function(x) x %in% tail(x, 2)))), ]

答案 3 :(得分:1)

try tail()。在R head函数中,您可以预览前n行,而在tail中,您可以预览后n行