У меня есть фрейм данных с именем «данные», который содержит столбец «дата», в котором указана дата события.
Я хочу добавить столбец, описывающий рассматриваемый «зимний сезон» (фактически период между августом одного года и августом другого года).
Для этого я делаю мутацию, которая берет дату и с case_when возвращает строку, соответствующую рассматриваемой зиме.
Например, если для данной строки указана дата 12 декабря 2017 года, блок кода заполнит новый столбец «зимний сезон» строкой «зима 2017-2018».
Это работает очень хорошо, но мой код тяжелый, и это заставило меня делать это вручную, ситуация за ситуацией. Я чувствую, что это можно упростить более элегантным способом и адаптировать к любому году. Что между первым августа года X и первым августа года Y он возвращает значение «зима x-y»?
Как написать этот блок кода более эффективно?
data <- data %>%
mutate(winter = case_when(
between(date, as.Date("2013-08-01"), as.Date("2014-08-01")) == TRUE ~ "winter 2013-2014",
between(date, as.Date("2014-08-01"), as.Date("2015-08-01")) == TRUE ~ "winter 2014-2015",
between(date, as.Date("2015-08-01"), as.Date("2016-08-01")) == TRUE ~ "winter 2015-2016",
between(date, as.Date("2016-08-01"), as.Date("2017-08-01")) == TRUE ~ "winter 2016-2017",
between(date, as.Date("2017-08-01"), as.Date("2018-08-01")) == TRUE ~ "winter 2017-2018",
between(date, as.Date("2018-08-01"), as.Date("2019-08-01")) == TRUE ~ "winter 2018-2019",
between(date, as.Date("2019-08-01"), as.Date("2020-08-01")) == TRUE ~ "winter 2019-2020",
between(date, as.Date("2020-08-01"), as.Date("2021-08-01")) == TRUE ~ "winter 2020-2021",
between(date, as.Date("2021-08-01"), as.Date("2022-08-01")) == TRUE ~ "winter 2021-2022",
between(date, as.Date("2022-08-01"), as.Date("2023-08-01")) == TRUE ~ "winter 2022-2023",
TRUE ~ "autre"
))





минимальный воспроизводимый пример значительно облегчит понимание проблемы, но, возможно, это поможет:
library(tidyverse)
library(lubridate)
#>
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#>
#> date, intersect, setdiff, union
data <- data.frame(name = 1:100,
date = seq.Date(from = as.Date("2013-08-01"),
to = as.Date("2022-08-01"),
length.out = 100))
data %>%
mutate(season = case_when(quarter(date, fiscal_start = 0) == 1 ~ "Summer",
quarter(date, fiscal_start = 0) == 2 ~ "Autumn",
quarter(date, fiscal_start = 0) == 3 ~ "Winter",
quarter(date, fiscal_start = 0) == 4 ~ "Spring"),
year = paste(year(date) - 1, year(date), sep = "-")) %>%
unite("season_and_year", c(season, year), sep = " ", remove = TRUE) %>%
head()
#> name date season_and_year
#> 1 1 2013-08-01 Winter 2012-2013
#> 2 2 2013-09-03 Spring 2012-2013
#> 3 3 2013-10-06 Spring 2012-2013
#> 4 4 2013-11-08 Spring 2012-2013
#> 5 5 2013-12-11 Summer 2012-2013
#> 6 6 2014-01-14 Summer 2013-2014
Created on 2022-05-16 by the reprex package (v2.0.1)
Вы можете рассчитать месяц и год от вашей даты. Тогда, если месяц < 8 (до августа), то зима от года-1 до года. В противном случае зима из года в год+1
data <- data %>%
mutate(
month=as.numeric(format(date,"%m")),
year=as.numeric(format(date,"%Y")),
winter=case_when(month<8 ~ paste0("Winter ",year-1,"-",year),
TRUE ~ paste0("Winter ",year,"-",year+1))
) %>%
select(-month,-year)
Можете ли вы предоставить некоторые из ваших данных через
dput? Вы можете сделатьdput(head(data)), а затем вставить результат в свой вопрос.