条件切片|从分组数据中过滤顶部和底部n行

时间:2017-11-20 23:01:10

标签: r dplyr

我遇到了一个问题,即从分组数据中同时过滤或切割顶部和底部n行。

所以它与此Select first and last row from grouped data

不同

如果sub_gr==a然后过滤|切片顶部三个行,我需要做什么 如果sub_gr==b然后过滤|切片底部两个行,那就是它!

我的数据是这样的

  df <- data.frame(gr=rep(seq(1,2),each=10),sub_gr=rep(rep(c("a","b"),each=5),2),
                   y = rep(c(sort(runif(5,0,0.5),decreasing=TRUE), sort(runif(5,0,0.5),,decreasing=TRUE)),2),
                   x = rep(c(seq(0.1,0.5,0.1),rev(seq(-0.5,-0.1,0.1))),2))

gr sub_gr          y      x
1   1      a 0.37851909  0.1
2   1      a 0.33305165  0.2
3   1      a 0.22478005  0.3
4   1      a 0.09677654  0.4
5   1      a 0.07060651  0.5
6   1      b 0.41999445 -0.1
7   1      b 0.35356301 -0.2
8   1      b 0.33274398 -0.3
9   1      b 0.20451400 -0.4
10  1      b 0.03714828 -0.5
11  2      a 0.37851909  0.1
12  2      a 0.33305165  0.2
13  2      a 0.22478005  0.3
14  2      a 0.09677654  0.4
15  2      a 0.07060651  0.5
16  2      b 0.41999445 -0.1
17  2      b 0.35356301 -0.2
18  2      b 0.33274398 -0.3
19  2      b 0.20451400 -0.4
20  2      b 0.03714828 -0.5

库(dplyr)

这是我尝试过的,

 df%>%
    group_by(gr, sub_gr)%>%
    slice(if(any(sub_gr=="a")) {row_number()==1:3} else {row_number()==4:n()})

Warning messages:
1: In 1:5 == 1:3 :
  longer object length is not a multiple of shorter object length
2: In 1:5 == 4:5L :
  longer object length is not a multiple of shorter object length
3: In 1:5 == 1:3 :
  longer object length is not a multiple of shorter object length
4: In 1:5 == 4:5L :
  longer object length is not a multiple of shorter object length

感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

可能有更优雅的解决方案,但我认为以下有效。我为可重复性设定了种子。

secondEquation[0]

答案 1 :(得分:1)

library(tidyverse)
# create a custom function to take the head or tail based on your rule
cond_slice <- function(x) {
  if (unique(x$sub_gr) == "a") {
    head(x, 3)
  } else {
    tail(x, 2)
  }
}
# create a column to split by and then map across the subsets
result <- x %>%
  unite(split_by, gr, sub_gr, remove = F) %>%
  split(.$split_by) %>%
  map(cond_slice) %>% 
  bind_rows() %>%
  select(-split_by)