r - 使用 if 语句和相似数量的样本进行 R 采样
问题描述
我需要从我的数据框中创建一个示例,为此我使用下面的代码。
name <- sample(c("Adam","John","Henry","Mike"),100,rep = TRUE)
area <- sample(c("run","develop","test"),100,rep = TRUE)
id <- sample(100:200,100,rep = FALSE)
mydata <- as.data.frame(cbind(id,area,name))
qcsample <- mydata %>%
group_by(area) %>%
nest() %>%
mutate(n = c(20, 15, 15)) %>%
mutate(samp = map2(data, n, sample_n)) %>%
select(area, samp) %>%
unnest()
现在,我得到了这些结果。
table(qcsample$area)
develop run test
15 15 20
--
table(qcsample$name)
Adam Henry John Mike
9 9 16 16
我想创建一个样本,每个名称的样本数量或多或少相同,例如。亚当 - 12 岁,亨利 - 12 岁,约翰 - 13 岁,迈克 - 13 岁。我怎样才能做到这一点?我可以以某种方式要求样本平均分布吗?
另外,在这个例子中,我使用了函数
样本_n
和指定数量的样本。
我预计有时不会有来自给定组的必需号码。在我的示例中,我从名为“test”的区域抽取 20 个样本,但有时只有 10 行包含“test”。总数是 50,所以我需要确保是否只有 10 个“测试”代码必须自动增加其他代码,所以示例将是“测试” - 10,“运行” - 20 和“开发” - 20 . 这可能发生在任何区域,所以我需要测试是否有足够的行来创建样本并增加其他区域。如果只有 1 个,则可以将其添加到任何剩余区域,或者如果差值为 3,我们将一个区域添加 1,将另一个区域添加 2。
考虑到所有可能性,我怎么能检查呢?我相信在这种情况下有八种排列。
在此先感谢 A。
解决方案
如果您使用的是虚构的数据,那么您可以创建每行的最小数量,然后创建填充以使您达到总数:
set.seed(42)
names <- c("Adam", "John", "Henry", "Mike")
areas <- c("run", "develop", "test")
totalrows <- 100
minname <- 22 # No less than 20 of each name (set to near threshold to test)
minarea <- 30 # No less than 30 of each area (less randomness the higher these are)
qcsample <- data.frame(
name=sample(c(rep(names, minname), sample(names, totalrows-length(names)*minname, replace=T))),
area=sample(c(rep(areas, minarea), sample(areas, totalrows-length(areas)*minarea, replace=T))),
id=sample(99+(1:totalrows))
)
这导致:
R> table(qcsample$name)
Adam Henry John Mike
23 28 24 25
R> table(qcsample$area)
develop run test
37 31 32
请注意,name
to的计数area
不受限制:
R> table(qcsample[,-3])
area
name develop run test
Adam 5 11 7
Henry 11 8 9
John 10 7 7
Mike 11 5 9
R>
使用@r2evans 建议的循环:
library(dplyr)
set.seed(42)
mydata <- data.frame(
name = sample(c("Adam","John","Henry","Mike"), 100, rep = TRUE),
area = sample(c("run","develop","test"), 100, rep = TRUE),
id = sample(100:200, 100, rep = FALSE)
)
Nsamples <- 50
mysample <- data.frame(sample_n(mydata, Nsamples))
minname <- 11 # max is 50/4 -> 12
minarea <- 15 # max is 50/3 -> 16
# the test you were asking about
while( (min(table(mysample$name)) < minname) || (min(table(mysample$area)) < minarea) ) {
mysample <- data.frame(sample_n(mydata, Nsamples))
}
这导致:
R> table(mysample$name)
Adam Henry John Mike
13 15 11 11
R> table(mysample$area)
develop run test
15 17 18
而且,像以前一样,区域没有最低限度的名称。
R> table(mysample[-3])
area
name develop run test
Adam 4 3 6
Henry 2 6 7
John 4 4 3
Mike 5 4 2
如果您需要为每个排列强制执行最小数量,请将其添加到测试中:
while(... || (min(table(mysample[-3])) < some_min)) {
顺便说一句,从表格中可以看出,排列的数量是名称的数量乘以区域的数量。
推荐阅读
- java - 如何使用 log4j2 将 JSON 结构作为源而不是消息记录到弹性搜索中
- github-actions - Github 操作在安装依赖项时失败
- python-3.x - 将函数应用于具有向量返回轴相关错误的数据框?
- html - 如何在 Beautiful Soup 对象(或类似的 HTML 结构)中打印某个级别的所有节点?
- python - 未定义变量的错误,不知道为什么会这样
- arrays - 使用 API 解码 JSON 并将产品添加到字典中的数组
- ios - AVRoutePicker 不会将音频输出到 Airplay 设备,但会输出到电话扬声器和耳机
- python - 如何在处理 KMeans 时避免内存泄漏,例如在此代码中,我试图找到在 KMean 聚类中使用的最佳 WCSS
- python - Flask SQLAlchemy 模型 - 使用 declaritive_base() 与 SQLAlchemy() 类实例化
- git - 如何将 VS 代码中的 git 分支与编辑选项进行比较?