r - 如何使用 R 中的 getData 包简化和加速循环
问题描述
我正在尝试下载一堆经纬度坐标的高分辨率气候数据,并将它们组合成一个数据框。我想出了一个解决方案(如下),但是我拥有的大量坐标列表将永远需要。我在 GIS StackExchange 上问了一个相关问题,看看是否有人知道下载和合并数据的更好方法,但我想知道我是否可以以某种方式加快循环的操作?有人对我如何做到这一点有任何建议吗?这是一个可重现的示例:
# Download and merge 0.5 minute MAT/MAP data from WorldClim for a list of lon/lat coordinates
# This is based on https://emilypiche.github.io/BIO381/raster.html
# Make a dataframe with coordinates
coords <- data.frame(Lon = c(-83.63, 149.12), Lat=c(10.39,-35.31))
# Load package
library(raster)
# Make an empty dataframe for dumping data into
coords3 <- data.frame(Lon=integer(), Lat=integer(), MAT_10=integer(), MAP_MM=integer())
# Get WorldClim data for all the coordinates, and dump into coords 3
for(i in seq_along(coords$Lon)) {
r <- getData("worldclim", var="bio", res=0.5, lon=coords[i,1], lat=coords[i,2]) # Download the tile containing the lat/lon
r <- r[[c(1,12)]] # Reduce the layers in the RasterStack to just the variables we want to look at (MAT*10 and MAP_mm)
names(r) <- c("MAT_10", "MAP_mm") # Rename the columns to something intelligible
points <- SpatialPoints(na.omit(coords[i,1:2]), proj4string = r@crs) #give lon,lat to SpatialPoints
values <- extract(r,points)
coords2 <- cbind.data.frame(coords[i,1:2],values)
coords3 <- rbind(coords3, coords2)
}
# Convert MAT*10 from WorldClim into MAT in Celcius
coords3$MAT_C <- coords3$MAT_10/10
编辑:感谢 Dave2e 的建议,我首先制作了一个列表,然后将中间结果放入列表中,并在最后进行 rbind。我还没有计时,看看它比我原来的解决方案快多少。如果有人对如何提高速度有进一步的建议,我会全力以赴!这是新版本:
coordsList <- list()
for(i in seq_along(coordinates$lon_stm)) {
r <- getData("worldclim", var="bio", res=0.5, lon=coordinates[i,7], lat=coordinates[i,6]) # Download the tile containing the lat/lon
r <- r[[c(1,12)]] # Reduce the layers in the RasterStack to just the variables we want to look at (MAT*10 and MAP_mm)
names(r) <- c("MAT_10", "MAP_mm") # Rename the columns to something intelligible
points <- SpatialPoints(na.omit(coordinates[i,7:6]), proj4string = r@crs) #give lon,lat to SpatialPoints
values <- extract(r,points)
coordsList[[i]] <- cbind.data.frame(coordinates[i,7:6],values)
}
coords_new <- bind_rows(coordsList)
Edit2:我使用 system.time() 来计算上述两种方法的执行时间。当我做计时时,我已经下载了所有的数据,所以下载时间不包括在我的时间估计中。我的第一种方法用了 45.01 分钟,而修改后的方法用了 44.15 分钟,所以我并没有真正看到后一种方法可以节省大量时间。仍然愿意接受有关如何修改代码的建议,以便我可以提高操作速度!
解决方案
推荐阅读
- laravel - 用 eloquent 获取一行虚拟数据
- c# - 当我按下项目的详细信息操作链接时出现此错误
- mysql - 在 SQL 中显示所有不同的电影类型和每个电影类型的平均 IMDb 评级
- python - 如何在 3D 图中旋转偏移文本?
- python - 随机变量 discord.py 的随机输出
- java - AWS 库导致 NoClassDefFoundError
- node.js - 验证 req.body 时的 JOI [ValidationError]
- java - 在 pageobject 类中声明 WebElementFacade 时获取空指针
- python - spiralpp:zipfile.BadZipFile:文件不是 zip 文件
- ios - iOS:如何更改 UIImage 的一部分的颜色?