我有一个过程,可以在一个月内为单个气象站创建一个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?循环是实现此目的的最佳方法吗?
答案 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)
以下解决方案使用rnoaa
和tidyverse
包中的功能。
请注意,我使用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
作为数据框