使用R语言循环从Nasapower库提取气候信息出错求助
解决Nasapower库循环提取气候数据的问题
你的代码存在几个关键问题,直接导致循环无法正常运行:
- 循环索引错误:
seq_along(nrow(api_decimal$site))完全无效——api_decimal$site是字符串向量,nrow()对向量返回NULL,应该用1:nrow(api_decimal)遍历所有站点。 - 坐标处理错误:你把经纬度拼接成带逗号的字符串后转数值,这会直接报错(字符串含非数字字符)。没必要拼接,直接用原始的
LAT_DEC和LONG_DEC数值列即可,且get_power的lonlat参数要求经度在前、纬度在后的数值向量。 - 日期参数错误:循环里用
dates = years会每次请求所有6年数据,重复浪费请求,应该用当前循环的单个年份。 - 结果未保存:每次循环覆盖
ag_d,最后只剩最后一个站点的最后一年数据,需要用列表收集所有结果再合并。
修正后的循环版本代码
library(nasapower) # 原始数据(去掉多余的site列) api_decimal<- data.frame ( AP_COD = c("LOM_A", "LOM_L", "LOM_M", "LOM_LA", "LOM_CO"), LAT_DEC = c(25.628, 25.641, 25.415, 25.435, 25.424), LONG_DEC = c(7.300, 7.314, 7.450, 7.449, 7.443) ) years <- 2014:2019 all_results <- list() result_idx <- 1 for (year in years) { for (j in 1:nrow(api_decimal)) { # 按要求构造经纬度向量:经度在前,纬度在后 current_lonlat <- c(api_decimal$LONG_DEC[j], api_decimal$LAT_DEC[j]) # 请求单站点单年份数据 ag_d <- get_power( community = "ag", lonlat = current_lonlat, pars = "T2M", dates = as.character(year), temporal_api = "daily" ) # 追加站点标识和年份,方便后续合并 ag_d$AP_COD <- api_decimal$AP_COD[j] ag_d$YEAR <- year # 存入结果列表 all_results[[result_idx]] <- ag_d result_idx <- result_idx + 1 # 可选:添加延迟,避免请求过频被API限流 Sys.sleep(1) } } # 合并所有结果为单个数据框 final_data <- do.call(rbind, all_results)
更简洁的批量处理版本(推荐用purrr)
library(nasapower) library(purrr) library(dplyr) # 生成所有站点×年份的请求组合 request_list <- expand.grid( AP_COD = api_decimal$AP_COD, LONG_DEC = api_decimal$LONG_DEC, LAT_DEC = api_decimal$LAT_DEC, YEAR = 2014:2019, stringsAsFactors = FALSE ) # 定义单请求函数 fetch_t2m <- function(lon, lat, year, ap_cod) { get_power( community = "ag", lonlat = c(lon, lat), pars = "T2M", dates = as.character(year), temporal_api = "daily" ) %>% mutate(AP_COD = ap_cod, YEAR = year) } # 批量请求并合并结果(.progress显示进度条) final_data <- pmap_dfr(request_list, ~fetch_t2m(lon = ..2, lat = ..3, year = ..4, ap_cod = ..1), .progress = TRUE)
注意事项
- 严格遵循
lonlat参数的顺序:经度在前,纬度在后,否则会请求到错误位置。 - 批量请求时建议添加延迟或使用进度条,避免触发NASA API的访问限制。
- 大型数据库可分批次处理,避免单次请求量过大。
内容的提问来源于stack exchange,提问作者Johanna Ramirez
相关产品推荐
相关产品推荐

