3

我正在努力创建一个矢量化功能解决方案,该解决方案将允许我复制分层随机抽样,而无需在多次迭代中进行替换。我能够在不替换的情况下进行一次采样,然后从数据集中删除这些行,然后从未采样的观察中重复该过程。不幸的是,我需要多次这样做,这使得这个手动选项变得不可能。

我尝试过使用 replicate() 函数,但是我只能对其进行采样,而无需为每次传递进行替换。它将选择的样本放回数据集中以进行下一次采样。

使用下面的代码,我希望该函数创建 30 个新数据集,这些数据集由“一”和“零”集中的 3 个唯一(以前未采样)行组成。因此,每个新数据集将有 6 个总观测值(3-1 和 3-0)并被命名为独特的(即“new_dat1”、“new_dat2”...“new_dat30”)。

如果可能的话,我希望在不使用 for 循环的情况下实现所有这些,因此首选“应用”系列中的某些内容。

set.seed(123)
dat <- data.frame(Outcome = round(runif(160, 0, 1)))
cust <- data.frame(Cust = rep(c("ABC", "DEF", "GHI"), c(45, 80, 35)))
dat <- cbind(cust, dat)

one <- subset(dat, Outcome == 1)
zero <- subset(dat, Outcome == 0)


# Manual option which is not sufficient    
################################################
# sample 1's and remove choosen obs from "one" dataset
set.seed(123)
index <- sample(1:nrow(one), 3, replace = FALSE)
new_dat1 <- one[index, ]
unused_one <- one[-index, ]

# sample 0's and remove choosen obs from "zero" dataset
set.seed(123)
index <- sample(1:nrow(zero), 3, replace = FALSE)
unused_zero <- zero[-index, ]

# combine the 3-1 and 3-0 samples into the first of 30 "new_datn" sets
new_dat1 <- rbind(new_dat1, zero[index, ])

# repeat, now sampling from "unused_one" and "unused_zero" to create "new_dat2" - "new_dat30"
################################################


# Failed attempt using the replicate() function
################################################
set.seed(123)
one_sample <- replicate(30, one[sample(nrow(one), 3, replace = FALSE), ], simplify = FALSE)
zero_sample <- replicate(30, zero[sample(nrow(zero), 3, replace = FALSE), ], simplify = FALSE)

更复杂的是,我在“dat”集中的 0 和 1 观察总数会不时变化,所以我可能总是有余数要处理。因此,该函数必须能够为每个“new_dat”采样 3,直到它遇到最终集的余数,无论值如何,它都可以进入最终的“new_dat”。

即使我能弄清楚如何解决矢量化函数中的采样问题,我真的会不知所措让该函数创建新数据集并适当地命名它们。

如果有人可以为我提供一些帮助,我将不胜感激。感谢您花时间阅读我的帖子。

4

1 回答 1

1

如果我正确理解了您的需求,这是一种解决方案。

首先只是对整个向量进行采样,也就是说,您只是要对行号进行随机排序:

sample_rows  <- sample(nrow(one))

然后为每个随机分布的行分配一个样本组(每组 3 个元素)。由于元素的数量可能不能被 3 整除,因此扩展向量的长度,使其与行数具有相同的长度。现在用下一组填充 NA(我认为这就是“最后一组的剩余部分”的意思):

sample_group <- rep(1:(length(sample_rows)%/% 3), each = 3)
length(sample_group) <- length(sample_rows)
sample_group[is.na(sample_group)] <- max(sample_group, na.rm = TRUE) + 1

因此,现在您有 24 个 3 样本和 1 个 2 样本,无需替换:

samples <- data.frame(sample_rows, sample_group)

head(samples)
  sample_rows sample_group
1          12            1
2           6            1
3          41            1
4          35            2
5          71            2
6          62            2

tail(samples)
   sample_rows sample_group
69          69           23
70          53           24
71          32           24
72          27           24
73          18           25
74          65           25

我为“一”的向量做了这个,但你可以很容易地为零的向量复制它并将它们组合起来。

split()PS:您可以使用和从 data.frame 中提取行lapply()。例如:

new_dat <- lapply(split(samples$sample_rows, samples$sample_group), function(x) one[x,])

new_dat一个包含所有 25 的列表也是如此data.frames。例如:

new_dat[[8]] # gives you the eigth data.frame

或者:

new_dat[[25]] # gives you the last data.frame
于 2015-04-23T02:31:25.573 回答