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

时间:2017-04-12 15:01:55

标签: r download rnoaa

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

我有一个df中的电台ID,看起来像下表(但还有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?循环是实现此目的的最佳方法吗?

3 个答案:

答案 0 :(得分:3)

你可以这样做。设置一个函数来读入数据,然后使用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))

答案 1 :(得分:2)

我喜欢这样的循环,因为它们更容易阅读和书写。你可以这样做,有两个循环:

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或其朋友。如果速度成为问题,您可能需要考虑它。

答案 2 :(得分:2)

以下解决方案使用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作为数据框