R中每日到标准气象周的转换
Conversion of daily to standard meteorological week in R
我在 SO 中看到很多关于使用 xts
、zoo
或 lubridate
包将每日数据转换为每周数据的问题。 None 个答案适合我的问题。我试过下面的代码
library(zoo)
library(lubridate)
library(xts)
library(tidyverse)
#Calculation for multistation
set.seed(123)
df <- data.frame("date"= seq(from = as.Date("1970-1-1"), to = as.Date("2000-12-31"), by = "day"),
"Station1" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 10, 30),
"Station2" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 11, 29),
"Station3" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 9, 28))
head(df)
# Aggregate over week
df %>%
mutate(Week = week(ymd(date)),
Year = year(ymd(date))) %>%
pivot_longer(-c(Week, date, Year), values_to = "value", names_to = "Station") %>%
group_by(Year, Week, Station) %>%
summarise(Weekly = mean(value)) %>%
arrange(Station) %>%
print(n = 55)
从输出中您可以看到 1970 包含 53 周,这是我不想要的。我想从每年的第一个日期开始一周,非闰年的第 52 周应该有 8 天,如果是闰年,第 9 周和第 52 周应该有 8 天,这样每年只有 52 周。如何在 R 中做到这一点?
您可以在一年中的某一天手动完成,不确定是否已经为此构建了一个函数。
df %>%
mutate(Week = pmin(52, ceiling(yday(date) / 7)),
Year = year(ymd(date)))
为什么不直接编写一个函数,根据您给出的定义给出气象周?包 lubridate
将为您提供一年中的第几天 yday
,它可以作为正确周标签向量的索引。这些可以通过简单的模块化数学和连接直接构建。
然后你只需要弄清楚你是否处于闰年,这同样可以使用 lubridate::leap_year
。将这些组合在一个 ifelse
中,你就有了一个易于使用的函数:
met_week <- function(dates)
{
normal_year <- c((0:363 %/% 7 + 1), 52)
leap_year <- c(normal_year[1:59], 9, normal_year[60:365])
year_day <- lubridate::yday(dates)
return(ifelse(lubridate::leap_year(dates), leap_year[year_day], normal_year[year_day]))
}
你可以做到
df %>% mutate(week = met_week(date))
我在 SO 中看到很多关于使用 xts
、zoo
或 lubridate
包将每日数据转换为每周数据的问题。 None 个答案适合我的问题。我试过下面的代码
library(zoo)
library(lubridate)
library(xts)
library(tidyverse)
#Calculation for multistation
set.seed(123)
df <- data.frame("date"= seq(from = as.Date("1970-1-1"), to = as.Date("2000-12-31"), by = "day"),
"Station1" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 10, 30),
"Station2" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 11, 29),
"Station3" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 9, 28))
head(df)
# Aggregate over week
df %>%
mutate(Week = week(ymd(date)),
Year = year(ymd(date))) %>%
pivot_longer(-c(Week, date, Year), values_to = "value", names_to = "Station") %>%
group_by(Year, Week, Station) %>%
summarise(Weekly = mean(value)) %>%
arrange(Station) %>%
print(n = 55)
从输出中您可以看到 1970 包含 53 周,这是我不想要的。我想从每年的第一个日期开始一周,非闰年的第 52 周应该有 8 天,如果是闰年,第 9 周和第 52 周应该有 8 天,这样每年只有 52 周。如何在 R 中做到这一点?
您可以在一年中的某一天手动完成,不确定是否已经为此构建了一个函数。
df %>%
mutate(Week = pmin(52, ceiling(yday(date) / 7)),
Year = year(ymd(date)))
为什么不直接编写一个函数,根据您给出的定义给出气象周?包 lubridate
将为您提供一年中的第几天 yday
,它可以作为正确周标签向量的索引。这些可以通过简单的模块化数学和连接直接构建。
然后你只需要弄清楚你是否处于闰年,这同样可以使用 lubridate::leap_year
。将这些组合在一个 ifelse
中,你就有了一个易于使用的函数:
met_week <- function(dates)
{
normal_year <- c((0:363 %/% 7 + 1), 52)
leap_year <- c(normal_year[1:59], 9, normal_year[60:365])
year_day <- lubridate::yday(dates)
return(ifelse(lubridate::leap_year(dates), leap_year[year_day], normal_year[year_day]))
}
你可以做到
df %>% mutate(week = met_week(date))