1

我有一个数据框,它由第一列(experiment.id)组成,其余列是与此实验 id 关联的值。每行都是一个唯一的实验 ID。我的数据框有 10⁴ - 10⁵ 的列。

data.frame(experiment.id=1:100, v1=rnorm(100,1,2),v2=rnorm(100,-1,2) )

这个数据框是我的样本空间的来源。我想做的是为每个唯一的experiment.id(行)随机抽样(替换)与此id相关的值v1,v2,....,v10000之一并构造一个样本s1。在每个样本 s1 中,都表示了所有实验 ID。

最终我想执行 10⁴ 样本,s1,s2,.....,s 10⁴ 并计算一些统计数据。

执行此采样过程的最有效方式(计算上)是什么。我想尽可能避免 for 循环。

更新: 我的问题不仅涉及采样,还涉及存储样本。我想我真正的问题是除了

d<-data.frame(experiment.id=1:1000, replicate (10000,rnorm(1000,100,2)) )
results<-data.frame(d$experiment.id,replicate(n=10000,apply(d[,2:10001],1,function(x){sample(x,size=1,replace=T)})))
4

3 回答 3

3

这是一个选择其中一列(不包括第一列)的表达式。它不会复制第一列,您需要将其作为单独的步骤提供。

对于数据框d

d[matrix(c(seq(nrow(d)), sample(ncol(d)-1, nrow(d), replace=TRUE)+1), ncol=2)]

那是一个样本。要获取N样本,只需将选择相乘(如约翰的回答):

mm <- matrix(c(rep(seq(nrow(d)), N), sample(ncol(d)-1, nrow(d)*N, replace=TRUE)+1), ncol=2)

result <- matrix(d[mm], ncol=N)

但是你会有记忆问题。

于 2012-12-28T15:25:11.850 回答
2

最短和最易读的恕我直言,仍然可以使用,但要充分利用向量化apply的事实:sample

results <- data.frame(experiment.id = d$experiment.id,
                      t(apply(d[, -1], 1, sample, 10000, replace = TRUE)))

如果 3 秒对您的需求来说太慢了,那么我建议您使用矩阵索引。

于 2012-12-28T16:33:05.293 回答
2

没有任何循环是可能的。如果将第一个列之后的列转换为矩阵,这将变得很容易,因为矩阵可以作为 [row, column] 或按顺序寻址,因为它是基础向量。

mat <- as.matrix(datf[,-1])
nr <- nrow(mat); nc <- ncol(mat)
sel <- sample( 1:nc, nr, replace = TRUE )
sel <- sel + ((1:nr)-1) * nc
x <- t(mat)[sel]
seldatf <- data.frame( datf[,1], x = x )

现在,要获得大量样本,只需将相同的逻辑相乘即可。

ns <- 10 # number of samples / row
sel <- sample(1:nc, nr * ns, replace = TRUE )
sel <- sel + rep(((1:nr)-1) * nc, each = ns)
x <- t(mat)[sel]
seldatf <- cbind( datf[,1],  data.frame(matrix(x, ncol = ns, byrow = TRUE)) )

如果您要设置ns <- 1e5并且有很多行,它可能会成为一个非常大的数据框。您可能需要注意内存不足。出于可读性的原因,我做了一些不必要的复制。您可以消除内存和速度的问题,因为一旦您使用大量内存,您将换出其他正在运行的程序。那很慢。您不必分配和保存 x、mat 甚至 sel。不这样做的结果将为您提供最快的答案。

于 2012-12-28T15:31:04.100 回答