Многошаговая петля для получения данных о погоде по годам и станциям

У меня есть процесс создания 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 как фрейм данных

Другие вопросы по тегам