【问题标题】:for loop with mutate only outputs last result带有 mutate 的 for 循环仅输出最后一个结果
【发布时间】:2020-11-22 20:50:02
【问题描述】:

很抱歉,如果它是重复的,并且由于缺乏可重复性,我不得不将文件链接给你。

我想要做的是:

假设我有一个带有坐标和名称的数据框

df <- tribble(
  ~Species, ~lat, ~lon,
  "a",42.92991, 11.875801,
  "b",42.92991, 11.875801,
  "c",43.91278, 3.513611,   
  "d",43.60851, 3.871755,   
  "e",39.24373, 9.120478
)

我还有一个文件夹有tifrasters,比如

files <- list.files(path="~/world/", pattern="*.tif$", full.name=TRUE, all.files=TRUE)

现在对于每次迭代,我想:

  • 使用文件名在数据框中创建一个新列
  • 在该列中插入对应latlon 的提取值

我试过使用这个for 循环,虽然在纸上看起来还不错,但我不明白为什么它只输出到funvar 最后一个结果。我不喜欢它覆盖结果而不是附加它。

如果我对 mutate 和更简单的对象使用类似的循环,它会附加它们,所以我不确定问题可能是什么

for(i in files){  
fraster<- raster(i)

fname<-gsub(".*//|[.].*", "", i)

funvar<-dplyr::mutate(fundata, !!fname:= raster::extract(fraster, coordinates(data.frame(lat,lon))))
}

谢谢!

【问题讨论】:

  • funvar &lt;- vector()放在for循环之前。然后使用funvar &lt;- c(funvar, dplyr::mutate(fundata, .... coordinates(data.frame(lat,lon)))) )
  • 嗨@maydin,通过这样做,我最终会得到一个包含每次运行的所有变量的向量(也就是说,不仅仅是我想添加的列)。我可以将其转换为数据框,但我会有Orc_speciesOrc_species.1Orc_species.2 等。

标签: r tidyverse geo


【解决方案1】:

我解决它的方法有点像 hack,但可以。我明确地将新列分配给数据框,如下所示。 我仍然不确定为什么 mutate 自己不这样做

for(i in files){  
fraster<- raster(i)

fname<-gsub(".*//|[.].*", "", i)

funvar<-dplyr::mutate(fundata, !!fname:= raster::extract(fraster, coordinates(data.frame(lat,lon))))

fundata[fname] <- funvar[[fname]]
}

【讨论】:

    【解决方案2】:

    根据您提供的信息,我无法判断这是否可行,但通常您会制作一个 RasterStack 并避免循环。

    library(raster)
    # NOTE the order of lon, lat`
    xy <- cbind(lon, lat)
    s <- stack(files)
    e <- raster::extract(s, xy)
    

    如果这不可能,你可以这样做

    fundata <- data.frame(xy)
    for (f in files){  
        fraster<- raster(f)
        fname <- gsub(".tif$", "", basename(f))
        fundata[[fname]] <- raster::extract(fraster, xy)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-10
      • 2018-06-05
      • 1970-01-01
      • 1970-01-01
      • 2020-05-06
      • 2019-02-08
      • 2015-06-17
      相关资源
      最近更新 更多