使用 sample_n() 函数进行替换采样的权重
Using weights for sampling with replacement with the sample_n() function
全部,
我有一个 dplyr sample_n()
问题。我正在尝试使用重量选项进行替换采样,但我似乎遇到了障碍。也就是说,放回抽样一直是对一个组的过度抽样。在没有替换的情况下进行采样不是我遇到的问题,但如果可以的话,我真的很想进行替换采样。
这是一个最小的工作示例,它使用来自 survey
包的熟悉的 apistrat
和 apipop
数据。 R 中的调查研究人员非常了解这些数据。在人口数据(apipop
)中,小学(stype == E
)约占所有学校的71.4%。中学(stype == M
)约占所有学校的 12.2%,高中(stype == H
)约占所有学校的 16.4%。 apistrat
故意不平衡,其中小学占数据的 50%,而初中和高中各占 200 行样本的剩余 25%。
我想做的是使用 sample_n()
函数对 apistrat
数据进行采样,并进行替换。然而,我似乎一直在对小学进行过采样,而对初中和高中进行过采样。这是 R 代码中的一个最小工作示例。请原谅我的玉米球循环代码。我知道我需要在 purrr
上做得更好,但我还没有做到。 :P
library(survey)
library(tidyverse)
apistrat %>% tbl_df() -> strat
apipop %>% tbl_df() -> pop
pop %>%
group_by(stype) %>%
summarize(prop = n()/6194) -> Census
Census
# p(E) = ~.714
# p(H) = ~.122
# p(M) = ~.164
strat %>%
left_join(., Census) -> strat
# Sampling with replacement seems to consistently oversample E and undersample H and M.
with_replace <- tibble()
set.seed(8675309) # Jenny, I got your number...
for (i in 1:1000) {
strat %>%
sample_n(100, replace=T, weight = prop) %>%
group_by(stype) %>%
summarize(i = i,
n = n(),
prop = n/100) -> hold_this
with_replace <- bind_rows(with_replace, hold_this)
}
# group_by means with 95% intervals
with_replace %>%
group_by(stype) %>%
summarize(meanprop = mean(prop),
lwr = quantile(prop, .025),
upr = quantile(prop, .975))
# ^ consistently oversampled E.
# meanprop of E = ~.835.
# meanprop of H = ~.070 and meanprop of M = ~.095
# 95% intervals don't include true probability for either E, H, or M.
# Sampling without replacement doesn't seem to have this same kind of sampling problem.
wo_replace <- tibble()
set.seed(8675309) # Jenny, I got your number...
for (i in 1:1000) {
strat %>%
sample_n(100, replace=F, weight = prop) %>%
group_by(stype) %>%
summarize(i = i,
n = n(),
prop = n/100) -> hold_this
wo_replace <- bind_rows(wo_replace, hold_this)
}
# group_by means with 95% intervals
wo_replace %>%
group_by(stype) %>%
summarize(meanprop = mean(prop),
lwr = quantile(prop, .025),
upr = quantile(prop, .975))
# ^ better in orbit of the true probability
# meanprob of E = ~.757. meanprob of H = ~.106. meanprob of M = ~.137
# 95% intervals include true probability as well.
我不确定这是否是 dplyr
(v. 0.8.3) 问题。有放回抽样的 95% 间隔不包括真实概率,并且每个样本(如果您达到峰值)始终处于 0.80 年代中期的小学抽样范围内。 1,000 个样本中只有三个(有替换)的构成中小学少于 100 行样本的 72%。就是那么一致。我很好奇这里是否有人对正在发生的事情有任何见解,或者我可能做错了什么,以及我是否误解了 sample_n()
.
的功能
提前致谢。
dplyr
中的 sample_n()
函数是 base::sample.int()
的包装器。看base::sample.int()
--实际功能是用C实现的,从源头可以看出问题:
rows <- sample(nrow(strat), size = 100, replace=F, prob = strat$prop)
strat[rows, ] %>% count(stype)
# A tibble: 3 x 2
stype n
<fct> <int>
1 E 74
2 H 14
3 M 12
rows <- sample(nrow(strat), size = 100, replace=T, prob = strat$prop)
strat[rows, ] %>% count(stype)
# A tibble: 3 x 2
stype n
<fct> <int>
1 E 85
2 H 8
3 M 7
老实说,我不太确定为什么会这样,但是如果您使概率总和为 1 并使它们在组内统一,那么它会给出预期的样本大小:
library(tidyverse)
library(survey)
data(api)
apistrat %>% tbl_df() -> strat
apipop %>% tbl_df() -> pop
pop %>%
group_by(stype) %>%
summarize(prop = n()/6194) -> Census
strat %>%
left_join(., Census) -> strat
#> Joining, by = "stype"
set.seed(8675309) # Jenny, I got your number...
with_replace <- tibble()
for (i in 1:1000) {
strat %>%
group_by(stype) %>%
mutate(per_prob = sample(prop/n())) %>%
ungroup() %>%
sample_n(100, replace=T, weight = per_prob) %>%
group_by(stype) %>%
summarize(i = i,
n = n(),
prop = n/100) -> hold_this
with_replace <- bind_rows(with_replace, hold_this)
}
with_replace %>%
group_by(stype) %>%
summarize(meanprop = mean(prop),
lwr = quantile(prop, .025),
upr = quantile(prop, .975))
#> # A tibble: 3 x 4
#> stype meanprop lwr upr
#> <fct> <dbl> <dbl> <dbl>
#> 1 E 0.713 0.63 0.79
#> 2 H 0.123 0.06 0.19
#> 3 M 0.164 0.09 0.24
由 reprex package (v0.3.0)
于 2020-04-17 创建
我猜这与 p 向量中的实体没有被 replace = TRUE
减少有关,但我真的不知道引擎盖下发生了什么。有C知识的应该看看!
全部,
我有一个 dplyr sample_n()
问题。我正在尝试使用重量选项进行替换采样,但我似乎遇到了障碍。也就是说,放回抽样一直是对一个组的过度抽样。在没有替换的情况下进行采样不是我遇到的问题,但如果可以的话,我真的很想进行替换采样。
这是一个最小的工作示例,它使用来自 survey
包的熟悉的 apistrat
和 apipop
数据。 R 中的调查研究人员非常了解这些数据。在人口数据(apipop
)中,小学(stype == E
)约占所有学校的71.4%。中学(stype == M
)约占所有学校的 12.2%,高中(stype == H
)约占所有学校的 16.4%。 apistrat
故意不平衡,其中小学占数据的 50%,而初中和高中各占 200 行样本的剩余 25%。
我想做的是使用 sample_n()
函数对 apistrat
数据进行采样,并进行替换。然而,我似乎一直在对小学进行过采样,而对初中和高中进行过采样。这是 R 代码中的一个最小工作示例。请原谅我的玉米球循环代码。我知道我需要在 purrr
上做得更好,但我还没有做到。 :P
library(survey)
library(tidyverse)
apistrat %>% tbl_df() -> strat
apipop %>% tbl_df() -> pop
pop %>%
group_by(stype) %>%
summarize(prop = n()/6194) -> Census
Census
# p(E) = ~.714
# p(H) = ~.122
# p(M) = ~.164
strat %>%
left_join(., Census) -> strat
# Sampling with replacement seems to consistently oversample E and undersample H and M.
with_replace <- tibble()
set.seed(8675309) # Jenny, I got your number...
for (i in 1:1000) {
strat %>%
sample_n(100, replace=T, weight = prop) %>%
group_by(stype) %>%
summarize(i = i,
n = n(),
prop = n/100) -> hold_this
with_replace <- bind_rows(with_replace, hold_this)
}
# group_by means with 95% intervals
with_replace %>%
group_by(stype) %>%
summarize(meanprop = mean(prop),
lwr = quantile(prop, .025),
upr = quantile(prop, .975))
# ^ consistently oversampled E.
# meanprop of E = ~.835.
# meanprop of H = ~.070 and meanprop of M = ~.095
# 95% intervals don't include true probability for either E, H, or M.
# Sampling without replacement doesn't seem to have this same kind of sampling problem.
wo_replace <- tibble()
set.seed(8675309) # Jenny, I got your number...
for (i in 1:1000) {
strat %>%
sample_n(100, replace=F, weight = prop) %>%
group_by(stype) %>%
summarize(i = i,
n = n(),
prop = n/100) -> hold_this
wo_replace <- bind_rows(wo_replace, hold_this)
}
# group_by means with 95% intervals
wo_replace %>%
group_by(stype) %>%
summarize(meanprop = mean(prop),
lwr = quantile(prop, .025),
upr = quantile(prop, .975))
# ^ better in orbit of the true probability
# meanprob of E = ~.757. meanprob of H = ~.106. meanprob of M = ~.137
# 95% intervals include true probability as well.
我不确定这是否是 dplyr
(v. 0.8.3) 问题。有放回抽样的 95% 间隔不包括真实概率,并且每个样本(如果您达到峰值)始终处于 0.80 年代中期的小学抽样范围内。 1,000 个样本中只有三个(有替换)的构成中小学少于 100 行样本的 72%。就是那么一致。我很好奇这里是否有人对正在发生的事情有任何见解,或者我可能做错了什么,以及我是否误解了 sample_n()
.
提前致谢。
dplyr
中的 sample_n()
函数是 base::sample.int()
的包装器。看base::sample.int()
--实际功能是用C实现的,从源头可以看出问题:
rows <- sample(nrow(strat), size = 100, replace=F, prob = strat$prop)
strat[rows, ] %>% count(stype)
# A tibble: 3 x 2
stype n
<fct> <int>
1 E 74
2 H 14
3 M 12
rows <- sample(nrow(strat), size = 100, replace=T, prob = strat$prop)
strat[rows, ] %>% count(stype)
# A tibble: 3 x 2
stype n
<fct> <int>
1 E 85
2 H 8
3 M 7
老实说,我不太确定为什么会这样,但是如果您使概率总和为 1 并使它们在组内统一,那么它会给出预期的样本大小:
library(tidyverse)
library(survey)
data(api)
apistrat %>% tbl_df() -> strat
apipop %>% tbl_df() -> pop
pop %>%
group_by(stype) %>%
summarize(prop = n()/6194) -> Census
strat %>%
left_join(., Census) -> strat
#> Joining, by = "stype"
set.seed(8675309) # Jenny, I got your number...
with_replace <- tibble()
for (i in 1:1000) {
strat %>%
group_by(stype) %>%
mutate(per_prob = sample(prop/n())) %>%
ungroup() %>%
sample_n(100, replace=T, weight = per_prob) %>%
group_by(stype) %>%
summarize(i = i,
n = n(),
prop = n/100) -> hold_this
with_replace <- bind_rows(with_replace, hold_this)
}
with_replace %>%
group_by(stype) %>%
summarize(meanprop = mean(prop),
lwr = quantile(prop, .025),
upr = quantile(prop, .975))
#> # A tibble: 3 x 4
#> stype meanprop lwr upr
#> <fct> <dbl> <dbl> <dbl>
#> 1 E 0.713 0.63 0.79
#> 2 H 0.123 0.06 0.19
#> 3 M 0.164 0.09 0.24
由 reprex package (v0.3.0)
于 2020-04-17 创建我猜这与 p 向量中的实体没有被 replace = TRUE
减少有关,但我真的不知道引擎盖下发生了什么。有C知识的应该看看!