我有一个数据框,其中包含第一列(experiment.id),其余列是与此实验ID关联的值。每行都是唯一的实验ID。我的数据框有10 in - 10⁵的列。
data.frame(experiment.id=1:100, v1=rnorm(100,1,2),v2=rnorm(100,-1,2) )
此数据框是我的示例空间的来源。我想做的是,每个独特的实验.id(行)随机抽样(替换)与该id相关联的值v1,v2,....,v10000之一,并构建样本s1。在每个样本s1中,表示所有实验ID。
最终我想要执行10⁴个样本,s1,s2,....,s10⁴并计算一些统计数据。
执行此采样过程的最有效方式(计算)。我想尽可能避免循环。
更新 我的问题不是关于采样而是存储样本。我想我真正的问题是,除了
之外,还有更快的方法来执行上述操作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)})))
答案 0 :(得分:3)
这是一个选择其中一列(不包括第一列)的表达式。它不会复制第一列,您需要将其作为单独的步骤提供。
对于数据框d
:
d[matrix(c(seq(nrow(d)), sample(ncol(d)-1, nrow(d), replace=TRUE)+1), ncol=2)]
这是一个样本。要获得N
个样本,只需乘以选择(如John的答案):
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)
但是你会遇到记忆问题。
答案 1 :(得分:2)
可以不做任何循环。如果将第一个列之后的列转换为矩阵,则这很容易,因为矩阵可以作为[行,列]或顺序地作为它的底层向量来寻址。
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。不这样做的结果将为您提供尽可能快的答案。
答案 2 :(得分:2)
最短且最易读的恕我直言仍然使用apply
,但充分利用sample
被矢量化的事实:
results <- data.frame(experiment.id = d$experiment.id,
t(apply(d[, -1], 1, sample, 10000, replace = TRUE)))
如果需要的3秒钟太慢,那么我建议您使用矩阵索引。