每组随机采样,制作一个新的数据框,重复直到组内的所有实体都被采样

Posted

技术标签:

【中文标题】每组随机采样,制作一个新的数据框,重复直到组内的所有实体都被采样【英文标题】:Randomly sample per group, make a new dataframe, repeat until all entities within a group are sampled 【发布时间】:2017-07-31 14:15:25 【问题描述】:

我想为每个区域随机抽取一个站点,创建一个新的数据框,然后重复这些过程,直到对所有站点进行采样。因此,每个数据框不会包含来自同一区域的同一站点。

我的真实数据框中的几个区域比其他区域有更多的站点(C 区有 4 个站点)。我想删除那些行(也许我应该在制作多个数据框之前这样做)。

这是一个示例数据框(真实的数据框有 >100 个区域和每个区域 >10 个站点):

mydf <- read.table(header = TRUE, text = 'V1 V2 Region Site 
5 1 A X1
5 6 A X2
8 9 A X3
2 3 B X1
3 1 B X2
7 8 B X3
1 2 C X1
9 4 C X2
4 5 C X3
6 7 C X4')

重复以下代码三次会生成包含给定区域的相同站点的数据帧(第二个和第三个表都具有区域 A 的站点 X2)。

do.call(rbind, lapply(split(mydf, mydf$Region), function(x) x[sample(nrow(x), 1), ]))

  V1 V2 Region Site
A  8  9      A   X3
B  2  3      B   X1
C  6  7      C   X4

V1 V2 Region Site
A  5  6      A   X2
B  7  8      B   X3
C  9  4      C   X2

  V1 V2 Region Site
A  5  6      A   X2
B  3  1      B   X2
C  6  7      C   X4

您能否帮我创建多个数据框,以便所有数据框都包含所有区域,但每个数据框都包含唯一的 Region-Site 组合。

编辑:这是预期的输出。为了产生这些,在第一次采样中,从每个区域中随机抽取一个站点(行)并制作一个数据框。在第二次抽样中,重复相同的过程,但无法绘制给定区域的相同站点。我想要的是包含 Region-Site 独特组合的独立数据框。

V1 V2 Region Site
5 1 A X1
7 8 B X3
1 2 C X1

V1 V2 Region Site
5 6 A X2
3 1 B X2
4 5 C X3

V1 V2 Region Site
8 9 A X3
2 3 B X1
9 4 C X2

【问题讨论】:

关于 R 编码的问题通常不在此处讨论。我认为这将成为Stack Overflow 的主题。如果您等待,我们可以尝试将其迁移到那里。 对不起。感谢您尝试迁移它。 你能显示预期的输出吗? 【参考方案1】:

伟大的data.table 包实际上使这非常容易

# Turn mydf into a data.table 
library(data.table)
setDT(mydf)

# Shuffle the rows of the table
dt <- dt[sample(.N)]

# In case there are multiple rows for a given Region <-> Site pair,
# eliminate duplicates.
dt <- unique(dt, by = c('Region', 'Site'))

# Get the first sample from each region group
# Note: .SD refers to the sub-tables after grouping by Region
dt[, .SD[1], by=Region]

# Get the second and third sample from each region group
dt[, .SD[2], by=Region]
dt[, .SD[3], by=Region]

事实上,你可以按照弗兰克的建议合并成一个单线

library(data.table)
dt <- setDT(mydf)
dt <- unique(dt, by = c('Region', 'Site'))
dt[sample(.N), .SD[1:3], by = Region]

【讨论】:

“消除重复”步骤也可以使用unique 完成。关于后面的部分,可能只是dt[, .SD[1:3], by=Region],因为 OP 只需要每个区域三个站点。作为旁注,我认为覆盖dt &lt;- 是不好的做法,因为它更难调试。 强调 OP 的清晰度。也添加了单行。 好的,不错的单行。顺便说一句,只是为了澄清。 dt &lt;- dt[...] 使代码不那么清晰,因为如果我想在这样的步骤之前弄清楚 dt 的样子,我需要从顶部再次运行代码。更简单的是newdt &lt;- dt[...]。单独的一点:使用setDT,无需分配。 mydf 本身已经变成了一个data.table,通过引用修改。【参考方案2】:

成功了!我没有看到接受答案的复选标记,所以我在这里做。

【讨论】:

以上是关于每组随机采样,制作一个新的数据框,重复直到组内的所有实体都被采样的主要内容,如果未能解决你的问题,请参考以下文章

提取数据框中每个组内的最大值[重复]

R重复功能直到满足条件

使用 GroupBy 合并组内的两个数据框

如何随机抽样删除一些组和随机删除组内的一些个人?

组内的 Cumsum 并在 pandas 的条件下重置

是否可以通过查询获得组中组内的随机值?