我有一个类似于此的数据框:
Factor1 Factor2 Value
1 A 1 -0.1169027
2 B 1 0.4153005
3 B 2 -1.8824073
4 B 3 0.2627502
5 C 1 0.8822784
6 C 2 0.5011568
7 C 3 0.2332566
8 C 4 0.1897866
9 C 5 -1.4404080
10 C 6 0.3414159
我感兴趣的是编写一段代码,根据Factor2中不同样本的最大数量,存储在每个Factor1级别的新数据帧bootstrap样本中。
library(tidyverse)
sampleGroups <- df %>%
group_by(Factor1) %>%
select(Factor1, Factor2) %>%
summarise(n_distinct(Factor2))
sampleGroups ## max = 6
一旦选择了Factor1的每个级别中的所有独特的Factor2水平,样本都需要更换。
因此上表的合适输出如下所示:
Factor1 Factor2 Value
1 A 1 -0.1169027
2 A 1 -0.1169027
3 A 1 -0.1169027
4 A 1 -0.1169027
5 A 1 -0.1169027
6 A 1 -0.1169027
7 B 1 0.4153005
8 B 2 1.8824073
9 B 3 0.2627502
10 B 1 0.4153005
11 B 2 -1.8824073
12 B 2 -1.8824073
13 C 1 0.8822784
14 C 2 0.5011568
15 C 3 0.2332566
16 C 4 0.1897866
17 C 5 -1.4404080
18 C 6 0.3414159
当你可以看到因子1 = A重复6次时,因子1 = B重复6次,但因子1(B)中的因子2在因子1(B)中选择因子2的所有水平后被重复引导,然后选择因子1(C)6次,因为这是发现最高数量的因子2的独特水平。
我的真实数据集有20个Factor1级别,17个独特级别的Factor2嵌套在Factor1中。
这样的事情在R中很容易实现吗?也许使用dplyr?我有一些代码可以从Factor2中为Factor1的每个级别随机选择一个样本,但我无法弄清楚如何强制它为Factor1的每个级别选择所有级别的Factor2(必要时)。
dfBoot <- tibble(Bootstrap = integer(0), Factor1 = character(0), Factor2 = character(0))
for (i in 1:10) {
selected <- df %>%
group_by(Factor1) %>%
select(Factor1, Factor2) %>%
sample_n(1) %>%
mutate(Bootstrap = i)
dfBoot <- bind_rows(dfBoot, selected)
}
dfBoot
# A tibble: 30 x 3
Bootstrap Factor1 Factor2
<int> <chr> <chr>
1 1 A 1
2 1 B 2
3 1 C 1
4 2 A 1
5 2 B 1
6 2 C 5
7 3 A 1
8 3 B 2
9 3 C 3
10 4 A 1
# ... with 20 more rows
将replace = TRUE
添加到上面的sample_n
行,会产生一个具有正确样本数的数据帧,但每个级别的因子2都是随机采样的,我需要将替换只发生一次已经选择了所有级别的因子2。
dfBoot <- tibble(Bootstrap = integer(0), Factor1 = character(0), Factor2 = character(0))
for (i in 1:10) {
selected <- df %>%
group_by(Factor1) %>%
select(Factor1, Factor2) %>%
# sample with replacement this time
sample_n(6, replace = TRUE) %>%
mutate(Bootstrap = i)
dfBoot <- bind_rows(dfBoot, selected)
}
# A tibble: 180 x 3
Bootstrap Factor1 Factor2
<int> <chr> <chr>
1 1 A 1
2 1 A 1
3 1 A 1
4 1 A 1
5 1 A 1
6 1 A 1
7 1 B 1
8 1 B 3
9 1 B 2
10 1 B 2
# ... with 170 more rows
dfBoot
答案 0 :(得分:1)
这应该可以解决问题。我们的想法是将数据拆分为Factor1
,然后rbind
将每个拆分拆分为重新采样,其大小为原始数据集中Factor1
的最大数量与因子数之差在每次拆分中Factor1
。
df %>%
mutate(max_n = max(Factor2)) %>%
split(.$Factor1) %>%
map_dfr(~rbind(., sample_n(., if(max(.$Factor2) == mean(.$max_n)) 0 else(mean(.$max_n) - max(.$Factor2)), replace = TRUE))) %>%
select(-max_n)
# Factor1 Factor2 Value
# 1 A 1 -0.1169
# 2 A 1 -0.1169
# 3 A 1 -0.1169
# 4 A 1 -0.1169
# 5 A 1 -0.1169
# 6 A 1 -0.1169
# 7 B 1 0.4153
# 8 B 2 -1.8824
# 9 B 3 0.2628
# 10 B 1 0.4153
# 11 B 1 0.4153
# 12 B 1 0.4153
# 13 C 1 0.8823
# 14 C 2 0.5012
# 15 C 3 0.2333
# 16 C 4 0.1898
# 17 C 5 -1.4404
# 18 C 6 0.3414