У меня есть CSV с четырьмя столбцами: идентификатор сайта, широта, долгота и дата. Мне нужно рассчитать среднюю дневную температуру и общее количество суточных осадков для каждого участка на каждую дату. Я пытаюсь использовать пакет «daymeter».
Все мои даты приходятся на 2017 год, поэтому для извлечения данных я использовал следующий код:
library(daymetr)
site_weather2017 <- download_daymet_batch(
file_location = "templateforweatherdata.csv",
start = 2017,
end = 2017,
internal = TRUE,
force = FALSE,
silent = FALSE,
path = tempdir(),
simplify = FALSE
)
Это дает мне объект Daymeter с данными о температуре/осадках за 365 дней для каждого местоположения по широте/долготе. Как мне сузить его, чтобы он соответствовал только дате, указанной в каждом столбце?
Я попробовал этот код:
finaldata <- list()
for( i in 1:length(site_weather2017)){
site <- site_weather2017[[i]]
site.dat <- site$data
#add a column of mean daily temperature
site.dat["tmean"] <- rowMeans(site.dat[,c("tmax..deg.c.","tmin..deg.c.")])
#choose timespan of interest
beginDate <- yday(as.Date(format = "%m-%d-%Y"))
# s.Date(alldata$Date, format = "%Y-%m-%d")
#subset to only timespan of interest
subSite <- subset(site.dat, yday %in% beginDate:beginDate)
subSite['precip'] <- subSite$prcp..mm.day.
#calculate mean daily temperature, and sum of precipitation
finaldata[[i]] <- data.frame(site=site$site, meanTemp=mean(subSite$tmean),
sumPrecip=base::sum(subSite$prcp..mm.day.))
}
Но температура и осадки отображаются как NaN.
library(readr)
library(dplyr)
library(daymetr)
## read the sites data
sites <- read_csv("templateforweatherdata.csv",
col_types = cols(date = col_date(format = "%m/%d/%Y")))
## we only need to download each site once, hence getting unique values
sites_unique <- sites %>% distinct(site, .keep_all = TRUE)
write.csv(sites_unique, "unique_templateforweatherdata.csv", row.names = F)
## using the unique site list for download
## we still will be processing the dates based on the original file
site_weather2017 <- download_daymet_batch(
file_location = "unique_templateforweatherdata.csv",
start = 2017,
end = 2017,
internal = TRUE,
force = FALSE,
silent = FALSE,
path = tempdir(),
simplify = FALSE
)
#> Downloading DAYMET data for: d22002 at 35.1527/-84.0396 latitude/longitude !
#> Done !
#> Downloading DAYMET data for: d22066 at 36.4246/-84.4666 latitude/longitude !
#> Done !
#> Downloading DAYMET data for: d22065 at 35.2741/-81.5184 latitude/longitude !
#> Done !
## creating an empty list to store the filtered data
site_weather2017_data <- list()
## looping over the downloaded data
for(i in seq_along(site_weather2017)) {
## getting desired dates for each site
site_dates <- subset(sites, site == site_weather2017[[i]]$site,
select = date)$date
## data for each site
site_weather2017[[i]]$data %>%
## adding columns for the header of each daymetr object
## i.e. site name, tile, lat/long/alt, and
## ... adding a column for date
mutate(site = site_weather2017[[i]]$site,
tile = site_weather2017[[i]]$tile,
latitude = site_weather2017[[i]]$latitude,
longitude = site_weather2017[[i]]$longitude,
altitude = site_weather2017[[i]]$altitude,
date = as.Date(as.numeric(yday), origin = paste0(year, "-01-01")),
.before = 1) %>%
## filtering for desired dates
filter(date %in% site_dates) -> site_weather2017_data[[i]]
}
## binding the rows together for a final dataframe
bind_rows(site_weather2017_data)
#> site tile latitude longitude altitude date year yday dayl..s.
#> 1 d22002 11208 35.1527 -84.0396 607 2017-11-01 2017 304 37960.51
#> 2 d22002 11208 35.1527 -84.0396 607 2017-11-08 2017 311 37193.35
#> 3 d22066 11388 36.4246 -84.4666 455 2017-11-15 2017 318 36175.83
#> 4 d22065 11210 35.2741 -81.5184 266 2017-01-22 2017 21 35987.47
#> prcp..mm.day. srad..W.m.2. swe..kg.m.2. tmax..deg.c. tmin..deg.c. vp..Pa.
#> 1 0.00 361.07 0 19.01 0.26 622.54
#> 2 10.84 97.65 0 18.38 13.12 1508.59
#> 3 0.00 291.03 0 13.50 0.62 638.79
#> 4 12.31 76.66 0 13.61 9.88 1217.81
Created on 2024-07-14 with reprex v2.0.2
Мои данные содержат около 340 сайтов, и каждому сайту нужны данные за 14 дней. Таким образом, CSV выглядит как список из ~ 4000 строк и 4 столбцов. Поскольку мне нужно 14 дат для каждого сайта, широта/долгота/дата одинаковы для 14 строк, и для каждой различается только дата. Может быть, здесь мой код путается?
@JElliott Посмотрите мой отредактированный ответ. Сначала я думал, что вам нужно получить данные для дат между ними, а не данные для каждой даты (думая, что у вас есть 2 строки на сайт с датой начала и окончания). Теперь я изменил его, чтобы фильтровать каждую дату, присутствующую в наборе данных CSV сайтов, и сохранять ее в отдельном списке фреймов данных (я также отфильтровал CSV по уникальным именам сайтов, чтобы не загружать один и тот же сайт несколько раз). Я также добавил дополнительные столбцы для информации, хранящейся в заголовке объектов Daymeter. В конце я связываю список в один фрейм данных, как вы просили. Надеюсь это поможет.
Я очистил свою среду и снова запустил ваш код, и он сработал прекрасно, спасибо! Это дает мне 14 дней для каждого с датой, указанной из 365. Знаете ли вы, как поместить объект Daymeter в фрейм данных, в котором указана только одна дата?