有约束的分层抽样
Stratified sampling with constraints
我是 R 的新手,请多多包涵。
所以我尝试以这样的方式执行分层抽样,它将使用 2 列层,但两列都满足特定值。
这是我的代码:
library(splitstackshape)
set.seed(1)
dat1 <- data.frame(ID = 1:100,
A = sample(c("AA", "BB", "CC", "DD", "EE"), 100, replace = TRUE),
B = sample(c(30,40,50),100,replace = TRUE), C = sample(c(1:10),100,replace = TRUE),
D = sample(c("CA", "NY", "TX"), 100, replace = TRUE),
E = sample(c("M", "F"), 100, replace = TRUE))
stratified(dat1, c("B", "C"), 0.1, select = list(B = 30, C = c(8:10)))
据我了解,此函数首先生成大小为 10% 的层,然后从中选择满足条件 B=30 和 c 在 8 到 10 之间的记录。
结果,层的大小从最初的 10% 减少了。
我的问题是,有什么方法可以生成一个由记录组成的层,其中 B 列的值为 30,而 C 列的值可以在 8 到 10 之间 nrow()
结果样本是原始数据框的 10%?
我正在使用 "splitstackshape" 中的 stratified()
。如果 stratified()
无法处理此问题,是否还有其他软件包可以执行此类操作?
根据你的数据,这似乎是不可能的,至少如果你是在不放回的情况下进行抽样的话。
idx <- which((dat1$B == 30) & (dat1$C %in% 8:10))
idx <- sample(idx, 0.1*nrow(dat1))
Error in sample.int(length(x), size, replace, prob) :
cannot take a sample larger than the population when 'replace = FALSE'
问题是验证这两个条件的行数不到您数据的 10%。向量 idx
只有长度 5。
idx
#[1] 15 18 43 60 93
dat1[idx, ]
# ID A B C D E
#15 15 DD 30 9 CA F
#18 18 EE 30 10 NY M
#43 43 DD 30 10 NY F
#60 60 CC 30 10 NY M
#93 93 DD 30 10 TX M
更新
从原始答案中的示例数据继续,我将使用两步过程:
创建一个包含您感兴趣级别的子集。
sub1 <- as.data.table(dat1)[B == 30 & C %in% 8:10][order(C)]
计算出您需要采样的百分比。在这里,我将最终的行数设置为 500,因为在提取子集时样本数据没有 1000 行。要获得所需的百分比,只需将所需的行数除以子集中的总行数即可...
rows_wanted <- 500
set.seed(2)
out <- stratified(sub1, "C", rows_wanted/nrow(sub1))
## Check how many rows we have per group
out[, .N, .(B, C)]
# B C N
# 1: 30 8 157
# 2: 30 9 169
# 3: 30 10 174
原回答
stratified
函数先过滤数据,再进行采样。考虑以下因素:
library(splitstackshape)
set.seed(1)
n <- 10000
dat1 <- data.frame(ID = sequence(n),
A = sample(c("AA", "BB", "CC", "DD", "EE"), n, replace = TRUE),
B = sample(c(30,40,50),n,replace = TRUE),
C = sample(c(1:10),n,replace = TRUE),
D = sample(c("CA", "NY", "TX"), n, replace = TRUE),
E = sample(c("M", "F"), n, replace = TRUE))
示例,如您所示。
mySample <- stratified(dat1, c("B", "C"), 0.1, select = list(B = 30, C = 8:10))
nrow(mySample)
# [1] 98
将其与输出中预期的行数进行比较:
as.data.table(dat1)[, .N, .(B, C)][B == 30 & C %in% 8:10, list(N = round(N * .1)), .(B, C)][order(C)]
# B C N
# 1: 30 8 31
# 2: 30 9 33
# 3: 30 10 34
并将以上内容与您从 stratified
函数中获得的内容进行比较。
mySample[, .N, .(B, C)]
# B C N
# 1: 30 8 31
# 2: 30 9 33
# 3: 30 10 34
我是 R 的新手,请多多包涵。
所以我尝试以这样的方式执行分层抽样,它将使用 2 列层,但两列都满足特定值。
这是我的代码:
library(splitstackshape)
set.seed(1)
dat1 <- data.frame(ID = 1:100,
A = sample(c("AA", "BB", "CC", "DD", "EE"), 100, replace = TRUE),
B = sample(c(30,40,50),100,replace = TRUE), C = sample(c(1:10),100,replace = TRUE),
D = sample(c("CA", "NY", "TX"), 100, replace = TRUE),
E = sample(c("M", "F"), 100, replace = TRUE))
stratified(dat1, c("B", "C"), 0.1, select = list(B = 30, C = c(8:10)))
据我了解,此函数首先生成大小为 10% 的层,然后从中选择满足条件 B=30 和 c 在 8 到 10 之间的记录。
结果,层的大小从最初的 10% 减少了。
我的问题是,有什么方法可以生成一个由记录组成的层,其中 B 列的值为 30,而 C 列的值可以在 8 到 10 之间 nrow()
结果样本是原始数据框的 10%?
我正在使用 "splitstackshape" 中的 stratified()
。如果 stratified()
无法处理此问题,是否还有其他软件包可以执行此类操作?
根据你的数据,这似乎是不可能的,至少如果你是在不放回的情况下进行抽样的话。
idx <- which((dat1$B == 30) & (dat1$C %in% 8:10))
idx <- sample(idx, 0.1*nrow(dat1))
Error in sample.int(length(x), size, replace, prob) :
cannot take a sample larger than the population when 'replace = FALSE'
问题是验证这两个条件的行数不到您数据的 10%。向量 idx
只有长度 5。
idx
#[1] 15 18 43 60 93
dat1[idx, ]
# ID A B C D E
#15 15 DD 30 9 CA F
#18 18 EE 30 10 NY M
#43 43 DD 30 10 NY F
#60 60 CC 30 10 NY M
#93 93 DD 30 10 TX M
更新
从原始答案中的示例数据继续,我将使用两步过程:
创建一个包含您感兴趣级别的子集。
sub1 <- as.data.table(dat1)[B == 30 & C %in% 8:10][order(C)]
计算出您需要采样的百分比。在这里,我将最终的行数设置为 500,因为在提取子集时样本数据没有 1000 行。要获得所需的百分比,只需将所需的行数除以子集中的总行数即可...
rows_wanted <- 500 set.seed(2) out <- stratified(sub1, "C", rows_wanted/nrow(sub1)) ## Check how many rows we have per group out[, .N, .(B, C)] # B C N # 1: 30 8 157 # 2: 30 9 169 # 3: 30 10 174
原回答
stratified
函数先过滤数据,再进行采样。考虑以下因素:
library(splitstackshape)
set.seed(1)
n <- 10000
dat1 <- data.frame(ID = sequence(n),
A = sample(c("AA", "BB", "CC", "DD", "EE"), n, replace = TRUE),
B = sample(c(30,40,50),n,replace = TRUE),
C = sample(c(1:10),n,replace = TRUE),
D = sample(c("CA", "NY", "TX"), n, replace = TRUE),
E = sample(c("M", "F"), n, replace = TRUE))
示例,如您所示。
mySample <- stratified(dat1, c("B", "C"), 0.1, select = list(B = 30, C = 8:10))
nrow(mySample)
# [1] 98
将其与输出中预期的行数进行比较:
as.data.table(dat1)[, .N, .(B, C)][B == 30 & C %in% 8:10, list(N = round(N * .1)), .(B, C)][order(C)]
# B C N
# 1: 30 8 31
# 2: 30 9 33
# 3: 30 10 34
并将以上内容与您从 stratified
函数中获得的内容进行比较。
mySample[, .N, .(B, C)]
# B C N
# 1: 30 8 31
# 2: 30 9 33
# 3: 30 10 34