我有一个包含三列的数据框:“x”、“y”、“measurement”。下面是一个例子。
df <- expand.grid(x = 1:5, y = 1:5)
set.seed(1)
df$measurement <- round(rnorm(nrow(df)),2)
head(df, n = 10)
我想根据存储在 x 中的 x 值从此数据框中抽取样本。采样 x 步骤的每个样本大小应为 n_sample.
换句话说,索引存储在原始数据框中的x中。我将首先对 x 进行采样,然后使用这些值从 df 中绘制行。这个过程需要重复n_sim次。
我可以使用循环来实现这一点,但它在 R 中非常缓慢且效率低下。我想使用 apply 一种函数或类似更快的方法。
# number of simulation
n_sim <- 20
# sample using x values (indexes)
x_vals <- unique(df$x)
# size of each sample
n_sample <- 3
# sampling
sample_xs <- replicate(n = n_sim,
sample(x_vals, n_sample, replace = F),
simplify = F)
# ***** SLOW R LOOP: NEEDS TO BE REPLACED ******
output_sampled <- list()
for(i in 1:n_sim){
output_sampled[[i]] <- df[df$x %in% sample_xs[[i]], ]
}
示例如下:
output_sampled[[1]]
在上面的示例中,在采样过程中选择了 x 值 1、4、5,以及它们与所有可能的 y 值和相应测量值的配对。这给了我们 15 个配对(有 5 个不同的 y 值,我们采样了 3 个 x 值,给出 3 * 5 = 15)。
nrow(output_sampled[[1]])
如何在 R 中用快速的东西替换低效的循环?
我不确定它是否更快(你可以给它们计时)但是单行是(在你的代码之后我不会重复)
output_sampled2 <- with(df, lapply(sample_xs, \(s) df[x %in% s, ] )
为循环使用
lapply
,为清晰起见使用with
(这样就不需要笨拙的df$x
)和匿名函数的新符号\(s)
。