使用if语句和相似数量的样本进行R采样

标签 r if-statement conditional-statements distribution sample

我需要从我的数据帧创建一个示例,为此我使用下面的代码。

 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。 我怎样才能做到这一点?我可以以某种方式要求样本均匀分布吗?

另外,在这个例子中我使用了函数

sample_n

和指定的样本数量。

我预计有时特定组中不会有所需的人数。在我的示例中,我从名为“test”的区域采集 20 个样本,但有时只有 10 行包含“test”。总数是 50,所以我需要确保如果只有 10 个“测试”,代码必须自动增加其他的,因此示例将是“测试”- 10、“运行”- 20 和“开发”- 20 .这可能发生在任何区域,因此我需要测试是否有足够的行来创建样本并增加其他区域。如果只有 1,则可以将其添加到任何剩余区域,或者如果差值为 3,我们将 1 添加到一个区域,将 2 添加到另一个区域。

考虑到所有可能性,我该如何检查?我相信在这种情况下有八种排列。

提前致谢。

最佳答案

如果您使用的是虚构数据,那么您可以创建每行的最小数量,然后创建填充符以使您达到总数:

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

请注意,namearea 的数量不受限制:

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)) {

顺便说一句,从表中可以看出,排列数是名称数乘以区域数。

关于使用if语句和相似数量的样本进行R采样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52140337/

相关文章:

将所有列中的文本替换为数据表 R 中的另一个文本

r - 从 R 中的线性模型中获取 R^2

r - Ifelse 有 3 个条件和 2 个结果

r - 如何使用ggplot在圆内随机散布点,而不会围绕中心聚集?

jquery - 在 jQuery 中制作 if 语句

javascript - 在 React JSX 中有条件地渲染组件部分

列表中的 VB.NET If-Else

mysql - 选择每月出现 n 次的特定列具有相似值的行

java - 在 "OR"语句中使用 "IF"

c - 在 C 中将 var 赋值给 var