Многошаговая петля для получения данных о погоде по годам и станциям
У меня есть процесс создания df для одной метеостанции за период единственного месяца. Тем не менее, у меня есть около 25 станций, которые я хотел бы получить данные об осадках за 5-летний период.
У меня есть идентификаторы станций в df, это выглядит как в таблице ниже (но с еще 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
Я знаком с основами циклов, которые работают для одного процесса. Есть ли способ настроить этот цикл, чтобы создать новый df с использованием названия округа и года в течение периода с 2006 по 2011 год для всех 25 станций? Является ли цикл лучшим способом сделать это?
3 ответа
Мне нравятся циклы для таких вещей, потому что их легче читать и писать. Вы можете сделать это так с двумя циклами:
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
Конечно, вы всегда можете настроить цикл для использования lapply
или это друзья. Если скорость стала проблемой, вы можете рассмотреть ее.
Вы могли бы сделать что-то вроде этого. Настройте функцию для чтения данных, а затем переберите свой df с помощью mapply
и за каждый год с 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))
В следующем решении используются функции из 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
как фрейм данных