在一个dataframe中每个组随机抽样n行
从这些问题 – R数据框的子集中的行的随机样本和数据框中的 样本随机行我可以很容易地看到如何随机地从df或“n”行中抽样(select)'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.
例如,只需从“粉红”颜色中抽取3个随机行 – 使用library(kimisc)
:
library(kimisc) sample.rows(subset(df, color == "pink"), 3)
或编写自定义function:
sample.df <- function(df, n) df[sample(nrow(df), n), , drop = FALSE] sample.df(subset(df, color == "pink"), 3)
但是,我想从该因子的每个级别抽样3(或n)个随机行。 即新的DF将有12行(蓝色3,红色3,黄色3,粉红色3)。 这显然可以运行几次,为每种颜色创buildnewdfs,然后将它们绑定在一起,但我正在寻找一个更简单的解决scheme。
您可以使用ave
将随机ID分配给具有特定因子水平的每个元素。 然后你可以select一定范围内的所有随机ID。
rndid <- with(df, ave(X1, color, FUN=function(x) {sample.int(length(x))})) df[rndid<=3,]
这有一个好处,就是保留原来的行顺序和行名,如果这是你感兴趣的东西。再加上你可以重新使用rndid
vector创build不同长度的子集相当容易。
在dplyr
0.3和更高版本中,这个工作正常:
df %>% group_by(color) %>% sample_n(size = 3)
旧版本的dplyr
(版本<= 0.2)
我开始用dplyr来回答这个问题 ,假设这会起作用:
df %.% group_by(color) %.% sample_n(size = 3)
但事实certificate,在0.2中sample_n.grouped_df
S3方法存在,但没有注册在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
大概这将在未来的更新中得到解决。
我会考虑我目前作为GitHub Gist托pipe的stratified
function 。
获取它:
library(devtools) ## To download "stratified" source_gist("https://gist.github.com/mrdwab/6424112")
和它一起使用:
stratified(df, "color", 3)
有几个不同的function,便于分层采样。 例如,你也可以采取一种“即时”的样本。
stratified(df, "color", 3, select = list(color = c("blue", "red")))
为了给你一个这个函数做什么的感觉,下面是stratified
的论点:
-
df
:input数据data.frame
-
group
:组成“分层”的一列或多列的字符向量。 -
size
:所需的样本大小。- 如果
size
是一个小于1的值,则从每个层中取一个相称的样本。 - 如果
size
是1或更大的单个整数,则从每个层取得该样本的数量。 - 如果
size
是一个整数向量,则为每个层采用指定数量的样本。 build议您使用命名向量 。 例如,如果您有两个阶层,“A”和“B”,并且您想从“A”中取5个样本,从“B”中取10个样本,则可以inputsize = c(A = 5, B = 10)
。
- 如果
-
select
:这允许您在采样过程中对这些组进行子集分类。 这是一个list
。 例如,如果你的group
variables是“组”,并且它包含三层“A”,“B”和“C”,但是你只想从“A”和“C”中抽样,你可以使用select = list(Group = c("A", "C"))
。 -
replace
:用于replace采样。
这是一个解决scheme。 我们将一个data.frame分解成颜色组。 从每个这样的组中,我们抽样3行。 结果,我们获得了data.frames的列表。
df2 <- lapply(split(df, df$color), function(subdf) subdf[sample(1:nrow(subdf), 3),] )
然后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