dplyr:选择每组的前半部分(或给定比例)

age*_*nis 0 r training-data dplyr

我的需要很简单:我有一个带有分组变量的 data.frame,如下所示:

library(dplyr)
proportion = 0.5; set.seed(1)
df = data.frame(id=1:6, name=c("a", "a", "b"), value=rnorm(6)) %>% arrange(name)
Run Code Online (Sandbox Code Playgroud)

我只想保留每组的前半部分(按 订购时id)。(我想使用可修改的比例而不是一半,比如 0.65,因为它用于训练/测试目的的数据拆分)

许多问题都回答了这个问题,但是有固定数量的行(使用top_n()这里)我不知道如何使它依赖于每个组的大小,使用dplyr. 我不想要,sample_frac()因为它会破坏id秩序。但是,我使用自定义函数分两步找到了解决方案:

myfunc = function(data, prop){head(data, nrow(data)*prop)}
splitted.data = split(df, df$name)
lapply(splitted.data, myfunc, prop=proportion) %>% bind_rows()
####   id name      value
#### 1  1    a -0.6264538
#### 2  2    a  0.1836433
#### 3  3    b -0.8356286
Run Code Online (Sandbox Code Playgroud)

但是我可以dplyr直接这样做吗?谢谢

kon*_*vas 5

您可以使用n()which 将为您提供分组 df 中的行数。它在内部不起作用,top_n但在内部起作用filter并且slice

df %>% 
  group_by(name) %>% 
  filter(row_number() <= proportion * n())
Run Code Online (Sandbox Code Playgroud)

或者

df %>% 
  group_by(name) %>% 
  slice(seq(proportion * n()))
Run Code Online (Sandbox Code Playgroud)