如何重复代码以更改R中的序列中的变量

时间:2018-10-18 17:33:52

标签: r function for-loop r-raster

这是我要重复的代码

A_1981 <- Base[1:12]]
B <- sum(A_1981)
MFI_1981 <- sum(A_1981^2)/B

基地是一个栅格砖

A_1981已经一年了

MFI_1981是最终结果

所以我必须继续下一年

A_1982 <- Base[13:24]]
B <- sum(A_1982)
MFI_1982 <- sum(A_1982^2)/B

要重复相同的代码,我认为只能替换名称中的值:

a <- seq(1,421,by=12)
b <- seq(12,432,by=12)
c <- seq(1981,2016, by=1)

然后在下一个第三年按顺序进行,就像这样

A_a[3] <- Base[[b[3]:c[3]]
B <- sum(A_a[3])
MFI_a[3] <- sum(A_[3]^2)/B

必须具有某种用于for或使其功能的方式。但是不知道从哪里开始。

2 个答案:

答案 0 :(得分:2)

以下内容使用mapply完成了您想要的操作,并在.GlobalEnv中仅创建了一个对象,我将其命名为MFI

由于您尚未发布数据集示例,因此我首先创建了向量Base

set.seed(2469)    # Make the results reproducible

n <- 432
Base <- sample(100, n, TRUE)

step <- 12
b <- seq(1 + step, n, by = step)
a <- seq(1, n - step, by = step)

MFI <- mapply(function(i, j) sum(Base[i:j]^2)/sum(Base[i:j]), a, b)


head(MFI)
#[1] 63.66472 70.54014 67.60567 53.15550 58.71111 65.37008

另一种方法是使用Map,就像@Parfait在他的评论中建议的那样。

obj <- Map(function(i, j) sum(Base[i:j]^2)/sum(Base[i:j]), a, b)
names(obj) <- paste("MFI", 1980 + seq_along(obj), sep = "_")

obj$MFI_1981
#[1] 63.66472

请注意,length(obj)35,因此最后一个objobj$MFI_2015,而不是问题中所说的MFI_2016。只需在代码开头加上n <- 444即可轻松解决。

答案 1 :(得分:2)

我认为您正在寻找类似的东西

示例数据(48层,即4个“年”)

library(raster)
f <- system.file("external/rlogo.grd", package="raster")
Base <- stack(rep(f, 4*4))

方法1

f <- function(year) {
    start <- (year-1981) * 12 + 1
    A <- Base[[start:(start+11)]]
    sum(A^2)/sum(A)
}

mfi <- lapply(1981:1984, f)
MFI <- stack(mfi)

方法2

for (year in 1981:1984) {
    start <- (year-1981) * 12 + 1
    A <- Base[[start:(start+11)]]
    mfi <- sum(A^2)/sum(A)
    writeRaster(mfi, paste0(year, ".tif"))
}

s <- stack(paste0(1981:1984, ".tif"))

方法3,使用mapply就像瑞·巴拉达斯(Rui Barradas)的回答一样,但固定为BaseRasterBrick(包括去年)的时间

n <- nlayers(Base)
a <- seq(1, n, by = 12)
mfi <- mapply(function(i, j) sum(Base[[i:j]]^2)/sum(Base[[i:j]]), a, a+11)
s <- stack(mfi)