在数据框中,对每个组随机抽取n行样本。

15 浏览
0 Comments

在数据框中,对每个组随机抽取n行样本。

从这些问题中 - 从R数据框的子集中随机抽取行 & 在数据框中随机抽取行 ,我可以很容易地看到如何从df中随机抽取(选择)'n'行,或者从df中的特定因子水平中随机抽取(选择)'n'行。

以下是一些示例数据:

df <- data.frame(matrix(rnorm(80), nrow=40))
df$color <-  rep(c("blue", "red", "yellow", "pink"), each=10)
df[sample(nrow(df), 3), ] #从df中随机抽取3行,无重复。

例如,只从'pink'颜色中随机抽取3行 - 使用library(kimisc)

library(kimisc)
sample.rows(subset(df, color == "pink"), 3)

或者编写自定义函数:

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行来自粉色)。显然可以多次运行这个过程,为每种颜色创建新的df,然后将它们绑定在一起,但我正在寻找一个更简单的解决方案。

0
0 Comments

问题出现的原因:用户想要从数据框中每个组中随机抽取n个样本,以满足卡方检验的样本大小条件。

解决方法:用户可以使用ave函数为具有特定因子水平的每个元素分配一个随机ID。然后,可以选择在特定范围内的所有随机ID。

代码如下:

rndid <- with(df, ave(X1, color, FUN=function(x) {sample.int(length(x))}))
df[rndid<=n,]

这种方法的优点是保留了原始行顺序和行名称(如果用户对此感兴趣的话)。此外,用户可以轻松地重用rndid向量来创建不同长度的子集。

在回答者与提问者的对话中,有两个问题需要解决。问题1)变量X1,选择数据框中的哪个变量似乎并不重要。问题2)当不同因子水平的观测数量不同时,该解决方案仍然有效。即,如果用户要求每个颜色抽取11行,它将返回10行。在真实数据中,这可能很有用,因为不同因子水平的观测/行数确实有所不同。

用户对解决方案的反馈是满意的,即使存在不平衡的组也可以正常工作。

然后,用户提出了一个新的问题,即如何使用解决方案来满足卡方检验的样本大小条件,即每个组至少抽取5个样本。

根据之前的解决方案,我们可以修改代码如下:

rndid <- with(df, ave(X1, color, FUN=function(x) {sample.int(length(x))}))
df2 <- df[rndid<=n,]
df3 <- df2[ave(df2$color, df2$color, FUN=function(x) {sum(x) >= 5}),]

在这个修改后的代码中,我们首先使用之前的方法随机抽取了n个样本。然后,我们使用ave函数计算每个颜色组的样本数量,并通过检查是否大于等于5来筛选出满足样本大小条件的组。

这样,用户就可以使用这个修改后的代码满足卡方检验的样本大小条件了。

0
0 Comments

问题的出现原因:在旧版本的dplyr(版本<=0.2)中,使用group_by和sample_n函数组合时,会出现问题,因为sample_n.grouped_df方法存在但没有在NAMESPACE文件中注册,导致无法调用该方法。

解决方法:在旧版本的dplyr中,可以通过显式调用dplyr:::sample_n.grouped_df方法来解决该问题。具体操作是先使用group_by函数对数据进行分组,然后使用dplyr:::sample_n.grouped_df函数进行抽样。

这个问题在dplyr 0.3版本中已经修复。

文章内容如下:

在dplyr的0.3版本及以后的版本中,下面的代码可以正常工作:

df %>% group_by(color) %>% sample_n(size = 3)

然而,在旧版本的dplyr(版本<=0.2)中,使用相同的代码会出现问题。在0.2版本中,虽然存在sample_n.grouped_df的S3方法,但没有在NAMESPACE文件中注册,所以无法调用该方法。为了解决这个问题,可以通过显式调用dplyr:::sample_n.grouped_df方法来进行抽样。具体操作是先使用group_by函数对数据进行分组,然后使用dplyr:::sample_n.grouped_df函数进行抽样。

以下是使用修复方法后的代码和输出结果:

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

可以预计,这个问题在未来的更新中将得到修复。

你使用的dplyr版本是多少?是trunk版本吗?

我尝试过使用cran上的0.2版本和从github安装的版本,结果都是一样的。

在dplyr 0.3版本中,这个问题得到了解决。这是我现在解决这个问题的最喜欢的方法。

有人能解释一下这个方法的概念吗?sample_n函数是否会回溯查看是否应用了group_by函数?

管道操作符%>%将每个步骤的结果传递给下一个函数,所以不需要“回溯”。运行x <- mtcars %>% group_by(cyl),然后查看x,你会发现它有一个新的class属性,以及许多其他属性(attributes(x)),所以任何后续的函数都“知道”它正在处理一个分组的数据框。

然后,许多其他的dplyr函数将具有专门针对grouped_df对象的S3方法。可以使用methods(sample_n)来查看。

这个方法与sample_frac函数很好地配合使用,以保持各类别的相对比例。

现在,在dplyr中可以使用slice_sample函数来实现这个功能。具体请参考dplyr的官方文档:https://dplyr.tidyverse.org/reference/slice.html

0