【发布时间】:2016-04-15 15:33:49
【问题描述】:
这是一个可重现的 for 循环示例。因为我想做 3000 次迭代,而且我的矩阵比这个可重现的例子大得多,所以计算机崩溃了。关于我该怎么做的任何想法?
我读到 R 中不推荐循环,而是网络建议使用向量和应用函数,但我无法使用这些函数构建我的公式...
矩阵:
row.names <- c('A2003','B2010','C2011','D2010','E2001','F2005','F2009','G2003','G2007','H2004','H2010')
sp1 <- c(4,83,1,2,4,3,1,5,7,2,4)
sp2 <- c(5,0,2,3,10,5,0,2,4,3,1)
sp3 <- c(7,2,4,8,7,2,4,83,1,5,7)
sp4 <- c(0,2,4,2,4,12,1,5,7,2,4)
Site <- c('A','B','C','D','E','F','F','G','G','H','H')
Year <- c('2003','2010','2011','2010','2001','2005','2009','2003','2007','2004','2010')
Obs <- c(1,1,1,4,9,6,8,2,5,2,3)
ID <- c('A2003','B2010','C2011','D2010','E2001','F2005','F2009','G2003','G2007','H2004','H2010')
df<- data.frame(row.names, sp1, sp2, sp3, sp4, Site, Year, Obs, ID)
rownames(df) <- df[,1]
df[,1] <- NULL
df
df.1 <- subset(df, Obs == 1)
df.more <- subset(df, Obs >= 2)
df.1
df.more
循环函数:
require (vegan)
iterations <- 3000
out <- vector("list", iterations)
for(i in 1:iterations){
rnd.more <- do.call(rbind, lapply(split(df.more, df.more$Site),
function(df.more) df.more[sample(nrow(df.more), 1,replace=FALSE) , ])
)
rnd.df <- rbind(df.1,rnd.more)
rnd.df.bc <- as.matrix(vegdist(rnd.df[1:4], method="bray"))
rnd.df.bc[lower.tri(rnd.df.bc,diag=TRUE)] <- NA
triang <- rnd.df.bc[!is.na(rnd.df.bc)]
mean.bc <- mean(triang)
out[[i]] <- list(rnd = rnd.df, bc = rnd.df.bc, ave = mean.bc)
}
提取结果:
all.rnd.df <- lapply(out, "[[", "rnd")
capture.output(all.rnd.df,file="all.rnd.df.txt")
all.rnd.df.bc <- lapply(out, "[[", "bc")
capture.output(all.rnd.df.bc,file="all.rnd.df.bc.txt")
all.triang <- lapply(out, "[[", "ave")
capture.output(all.triang,file="all.triang.txt")
【问题讨论】:
-
备注:R允许将函数名指定为字符串,但这是类型系统颠覆废话,不要这样做;直接使用函数名。在你的情况下,这意味着:写 `
[[` 而不是"[["。 -
素食主义者从何而来?
-
@A. Idigoras,请注意,如果您不包含所有必要的软件包,您的示例就不能真正重现。
vegdist来自vegan包。一旦我弄清楚了,这个例子就运行得很好。 -
嗨@Heroka,我正在使用 vegan 包中的 vegdist (method="bray"),因为我想为每次迭代创建一个基于物种(从 1 到 4 的列)的相似性矩阵.
-
您可以将很多操作移出迭代循环。例如,当您可以只创建一次采样索引列表并在循环中引用它时,为什么要在循环中每次采样。与您的
rbinds 相同。您可以创建一个主data.frame并将预采样索引传递给它。
标签: r for-loop iteration output lapply