在数据帧中为每组采样n个随机行

jal*_*pic 24 random r sample dataframe

从这些问题- 从R数据帧的子集的行的随机样品 & 在数据帧样本随机行 我可以很容易地看到如何随机抽样(选择)"N"行从DF,或者"n"个来自特定级发起行df中的因子.

以下是一些示例数据:

df <- data.frame(matrix(rnorm(80), nrow=40))
df$color <-  rep(c("blue", "red", "yellow", "pink"), each=10)

df[sample(nrow(df), 3), ] #samples 3 random rows from df, without replacement.
Run Code Online (Sandbox Code Playgroud)

例如,从"粉红色"颜色中抽取3个随机行 - 使用library(kimisc):

library(kimisc)
sample.rows(subset(df, color == "pink"), 3)
Run Code Online (Sandbox Code Playgroud)

或编写自定义功能:

sample.df <- function(df, n) df[sample(nrow(df), n), , drop = FALSE]
sample.df(subset(df, color == "pink"), 3)
Run Code Online (Sandbox Code Playgroud)

但是,我想从每个级别的因子中抽取3(或n)个随机行.即新的df将有12行(蓝色3个,红色3个,黄色3个,粉红色3个).显然可以多次运行,为每种颜色创建newdf,然后将它们绑定在一起,但我正在寻找一种更简单的解决方案.

jor*_*ran 29

dplyr0.3及更高版本中,这可以正常工作:

df %>% group_by(color) %>% sample_n(size = 3)
Run Code Online (Sandbox Code Playgroud)

旧版本dplyr(版本<= 0.2)

我开始使用dplyr来回答这个问题,假设这会起作用:

df %.% group_by(color) %.% sample_n(size = 3)
Run Code Online (Sandbox Code Playgroud)

但事实证明,在0.2中,sample_n.grouped_dfS3方法存在,但未在NAMESPACE文件中注册,因此从未调度过.相反,我必须这样做:

df %.% group_by(color) %.% dplyr:::sample_n.grouped_df(size = 3)
Source: local data frame [12 x 3]
Groups: color

            X1         X2  color
8   0.66152710 -0.7767473   blue
1  -0.70293752 -0.2372700   blue
2  -0.46691793 -0.4382669   blue
32 -0.47547565 -1.0179842   pink
31 -0.15254540 -0.6149726   pink
39  0.08135292 -0.2141423   pink
15  0.47721644 -1.5033192    red
16  1.26160230  1.1202527    red
12 -2.18431919  0.2370912    red
24  0.10493757  1.4065835 yellow
21 -0.03950873 -1.1582658 yellow
28 -2.15872261 -1.5499822 yellow
Run Code Online (Sandbox Code Playgroud)

据推测,这将在未来的更新中修复.


A5C*_*2T1 7

我会考虑我的stratified功能,目前作为GitHub Gist托管.

得到它:

library(devtools)  ## To download "stratified"
source_gist("https://gist.github.com/mrdwab/6424112")
Run Code Online (Sandbox Code Playgroud)

并使用它:

stratified(df, "color", 3)
Run Code Online (Sandbox Code Playgroud)

有几种不同的功能便于分层采样.例如,您也可以采取样品"即时".

stratified(df, "color", 3, select = list(color = c("blue", "red")))
Run Code Online (Sandbox Code Playgroud)

为了让您了解函数的作用,以下是以下参数stratified:

  • df:输入 data.frame
  • group:构成"分层"的一列或多列的字符向量.
  • size:所需的样本大小.
    • 如果size值小于1,则从每个层中取出一个比例样本.
    • 如果size是1或更大的单个整数,则从每个层中获取该样本数.
    • 如果size是整数向量,则为每个层获取指定数量的样本.建议您使用命名向量.例如,如果你有两个分层,"A"和"B",你想要5个样本来自"A",10个来自"B",你会输入size = c(A = 5, B = 10).
  • select:这允许您在采样过程中对组进行子集化.这是一个list.例如,如果您的group变量是"Group",并且它包含三个层,"A","B"和"C",但您只想从"A"和"C"中采样,您可以使用select = list(Group = c("A", "C")).
  • replace:用于替换的取样.


gag*_*ews 6

这是一个解决方案.我们将data.frame拆分为颜色组.然后我们从每组中抽取3行.这会生成data.frames列表.

df2 <- lapply(split(df, df$color),
   function(subdf) subdf[sample(1:nrow(subdf), 3),]
)
Run Code Online (Sandbox Code Playgroud)

为了获得所需的结果,我们将data.frames列表合并为1个data.frame:

do.call('rbind', df2)
##                    X1          X2  color
## blue.3    -1.22677188  1.25648082   blue
## blue.4    -0.54516686 -1.94342967   blue
## blue.1     0.44647071  0.16283326   blue
## pink.40    0.23520296 -0.40411906   pink
## pink.34    0.02033939 -0.32321309   pink
## pink.33   -1.01790533 -1.22618575   pink
## red.16     1.86545895  1.11691250    red
## red.11     1.35748078 -0.36044728    red
## red.13    -0.02425645  0.85335279    red
## yellow.21  1.96728782 -1.81388110 yellow
## yellow.25 -0.48084967  0.07865186 yellow
## yellow.24 -0.07056236 -0.28514125 yellow
Run Code Online (Sandbox Code Playgroud)


MrF*_*ick 6

您可以使用随机ID为具有特定因子级别的每个元素分配ave.然后,您可以选择特定范围内的所有随机ID.

rndid <- with(df, ave(X1, color, FUN=function(x) {sample.int(length(x))}))
df[rndid<=3,]
Run Code Online (Sandbox Code Playgroud)

这样做的好处是可以保留原始行顺序和行名称,如果这是您感兴趣的话.另外,您可以rndid相当容易地重复使用向量来创建不同长度的子集.