多步循环获取多年和站点的天气数据

Multi step loop to acquire weather data over years and stations

我有一个过程可以在单个月份内为单个气象站创建 df。但是,我有大约 25 个站点想要获取 5 年以上的降水数据。

我在 df 中有站 ID,看起来像下面的 table(但还有 23 个站。

stationid           County
GHCND:USW00093721   ANNEARUNDEL
GHCND:USC00182308   BALTIMORE

天气数据集通过以下代码获取

library("rnoaa")
ANNEARUNDEL_2006 <- ncdc(datasetid='GHCND', stationid = "GHCND:USC00182060", datatypeid='PRCP', startdate = '2006-07-01', enddate = '2006-08-01', limit=400, token =  "API KEY") 

ANNEARUNDEL_2006 <- ANNEARUNDEL_2006$data

我非常熟悉适用于一个进程的非常基本的 for 循环。有没有一种方法可以设置这个循环,在 2006 年到 2011 年的跨度内为所有 25 个站使用县名和年份创建一个新的 df?循环是完成此任务的最佳方法吗?

我喜欢这样的循环,因为它们更易于阅读和编写。你可以用两个循环来做到这一点:

my_df <- read.table(text = "stationid   County
GHCND:USW00093721   ANNEARUNDEL
GHCND:USC00182308   BALTIMORE",
                    header = T)

library(rnoaa)

results <- list() # list as storage variable for the loop results
i <- 1 # indexing variable

for(sid in unique(my_df$stationid)) { # each station in your stationid dataframe
    for(year in 2006:2011) { # each year you care about
        data <- ncdc(datasetid='GHCND', stationid = sid,
                     datatypeid='PRCP', startdate = paste0(year, '-01-01'),
                     enddate = paste0(year, '-12-31'), limit=400, token = "API KEY")$data # subset the returned list right away here with $data

        # add info from each loop iteration
        data$county <- my_df[my_df$stationid == sid,]$County
        data$year <- year

results[[i]] <- data # store it
i <- i + 1 # rinse and repeat
    }
}
one_big_df <- do.call(rbind, results) # stack all of the data frames together rowwise

当然,您始终可以将 for 循环调整为使用 lapply 或其朋友。如果速度成为问题,您可能需要考虑一下。

你可以这样做。设置一个函数来读取数据,然后用 mapply 循环遍历你的 df,每年用 lapply 循环。输出将是一个命名的数据列表(就目前而言是矢量,尽管如果需要,您可以捕获更多 df 列,在这种情况下它们将是数据帧)。

getNCDC <- function(id,County,year){
  df <- ncdc(datasetid='GHCND', stationid = id, datatypeid='PRCP', startdate = paste0(year,'-07-01'), enddate = paste0(year,'-08-01'), limit=400, token =  "API KEY") 
  df <- list(df$data)
  names(df) <- paste(County,year,sep="_")
  return(df)
}

allData <- lapply(2006:2011,function(year) mapply(getNCDC,df$stationid,df$County,year))

以下解决方案使用 rnoaatidyverse 包中的函数。

请注意,我使用 ghcnd_search 下载降水数据。

# Load packages
library(rnoaa)
library(tidyverse)

# Create example data frame
sample_df <- data.frame(stationid = c("USW00093721", "USC00182308"),
                        County = c("ANNEARUNDEL", "BALTIMORE"),
                        stringsAsFactors = FALSE)

# Download the data use map. 
data_list <- map(sample_df$stationid, ghcnd_search, 
                 date_min = "2006-01-01", date_max = "2011-12-31", var = "prcp")

现在每个站点的prcp数据都作为数据帧下载。它们都作为列表存储在 data_list 中。

您可以通过访问列表的方式访问各个站点的数据,也可以将列表中的数据转换为单个数据框。这是一个例子:

# Transpost the data_list. Turns a list-of-lists "inside-out"
data_list2 <- transpose(data_list)

# Combine all data to a single data frame
data_df <- bind_rows(data_list2$prcp)

现在所有的数据都在data_df作为一个数据框