【问题标题】:How to repeat codes changing the variables in a sequence in R如何重复代码更改R中序列中的变量
【发布时间】:2019-03-23 14:11:47
【问题描述】:

这是我要重复的代码

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 或 make 一个函数。但不知道从哪里开始。

【问题讨论】:

  • 你需要在全局环境中创建这些对象吗?
  • 我认为您在最后一段代码中混淆了 a、b 和 c...

标签: r function for-loop r-raster


【解决方案1】:

以下使用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 &lt;- 444 来轻松解决。

【讨论】:

  • 或者使用简化的包装器到mapply,Map,并根据OP的需要返回一个元素列表(不是向量)甚至命名项目:MFI_1981MFI_1982, ... obj$MFI_1981, obj$MFI_1982 参考。
【解决方案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)

【讨论】:

    猜你喜欢
    • 2021-03-31
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多