首页 > 解决方案 > 如何使用 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 分钟,所以我并没有真正看到后一种方法可以节省大量时间。仍然愿意接受有关如何修改代码的建议,以便我可以提高操作速度!

标签: rloops

解决方案


推荐阅读