Формат даты-времени как сезонов в R?

В R можно отформатировать объекты даты POSIXlt как месяц:

format(Sys.time(), format='%Y-%m') 

Есть ли способ сделать то же самое с сезонами или 3-месячными группами (DJF, MAM, JJA, SON)? Эти разделения действительно распространены в климатологической и экологической науке, и было бы здорово иметь аккуратный способ быстро форматировать их, как месяцы. Очевидно, DJF приходится на 2 года, но для целей или этого вопроса это не имеет особого значения – просто последовательно вставляйте их в любой год (или, в идеале, было бы хорошо указать, в каком году они входят) ,

Я использую вывод как индекс for by() , поэтому формат вывода не имеет большого значения, так же, как каждый год / сезон уникален.

Изменить: пример данных:

 dates <- Sys.Date()+seq(1,380, by=35) dates <- structure(c(16277, 16312, 16347, 16382, 16417, 16452, 16487, 16522, 16557, 16592, 16627), class = "Date") dates #[1] "2014-07-26" "2014-08-30" "2014-10-04" "2014-11-08" "2014-12-13" # "2015-01-17" "2015-02-21" "2015-03-28" "2015-05-02" "2015-06-06" "2015-07-11" 

должно привести к:

 c("2014-JJA", "2014-JJA", "2014-SON", "2014-SON", "2015-DJF", "2015-DJF", "2015-DJF", "2015-MAM", "2015-MAM", "2015-JJA", "2015-JJA") 

Но «2015-DJF» также может быть «2014-DJF». Кроме того, форма вывода не имеет значения – «2104q4 или 201404 также будет в порядке.

as.POSIXlt возвращает именованный список (что делает его непригодным для столбцов data.frame). Столбцы списка могут быть индивидуально доступны и включать «год» (1900, в отличие от 1970, используемых для дефолта) и «mon» (на основе 0). Лучшее место для просмотра этого списка в справочной системе hte ?DateTimeClasses :

Сначала просто расчет сезонов, затем расчет за год-сезон

  c('DJF', 'MAM', 'JJA', 'SON')[ # select from character vector with numeric vector 1+((as.POSIXlt(dates)$mon+1) %/% 3)%%4] [1] "JJA" "JJA" "SON" "SON" "DJF" "DJF" "DJF" "MAM" "MAM" "JJA" [11] "JJA" paste( 1900 + # this is the base year for POSIXlt year numbering as.POSIXlt( dates )$year + 1*(as.POSIXlt( dates )$year==12) , # offset needed for December c('DJF', 'MAM', 'JJA', 'SON')[ # indexing from 0-based-mon 1+((as.POSIXlt(dates)$mon+1) %/% 3)%%4] , sep="-") [1] "2014-JJA" "2014-JJA" "2014-SON" "2014-SON" "2014-DJF" [6] "2015-DJF" "2015-DJF" "2015-MAM" "2015-MAM" "2015-JJA" [11] "2015-JJA" 

Не должно быть так сложно сделать функцию, которая строит форматирование, которое вы ожидаете. Это просто по модулю арифметика значений POSIXlt за месяц и год.

Мне нравится использовать вектор поиска для таких проблем, например:

 x <- as.POSIXlt( seq.Date(as.Date("2000-01-01"),as.Date("2002-01-01"),by="2 months") ) 

Например, если вы хотите указать сезоны южного полушария, вы можете сделать:

 src <- rep(c("su","au","wi","sp"),each=3)[c(2:12,1)] paste(format(x,"%Y-%m"),src[x$mon+1]) # [1] "2000-01 su" "2000-03 au" "2000-05 au" "2000-07 wi" "2000-09 sp" # [6] "2000-11 sp" "2001-01 su" "2001-03 au" "2001-05 au" "2001-07 wi" #[11] "2001-09 sp" "2001-11 sp" "2002-01 su" 

Измените имена src как вам удобно, чтобы переclassифицировать категории.

Пусть Q1 – DJF; Q2, MAM; и т.д., то:

 seasonal.quarters <- function(x) { x <- as.POSIXlt(x) x$mon <- (x$mon + 1) %% 12 quarters(x) } options(stringsAsFactors=FALSE) nonleap.year <- seq(from=as.POSIXct('2013-1-1'), to=as.POSIXct('2014-1-1'), by='day') d <- data.frame(ms=months(nonleap.year), qs=seasonal.quarters(nonleap.year)) by(d, INDICES=list(d$qs), FUN=function(x) unique(x$ms)) # : Q1 # [1] "January" "February" "December" # ------------------------------------- # : Q2 # [1] "March" "April" "May" # ------------------------------------- # : Q3 # [1] "June" "July" "August" # ------------------------------------- # : Q4 # [1] "September" "October" "November" leap.year <- seq(from=as.POSIXct('2016-1-1'), to=as.POSIXct('2017-1-1'), by='day') d <- data.frame(ms=months(leap.year), qs=seasonal.quarters(leap.year)) by(d, INDICES=list(d$qs), FUN=function(x) unique(x$ms)) # : Q1 # [1] "January" "February" "December" # ------------------------------------- # : Q2 # [1] "March" "April" "May" # ------------------------------------- # : Q3 # [1] "June" "July" "August" # ------------------------------------- # : Q4 # [1] "September" "October" "November" 

Это альтернатива 42-м ответу выше. Идите посмотреть мой комментарий там по той причине, что я разместил его.

 dates_orig <- as.POSIXlt(c("2013-01-01", "2013-02-01", "2013-03-01", "2013-04-01", "2013-05-01", "2013-06-01", "2013-07-01", "2013-08-01", "2013-09-01", "2013-10-01", "2013-11-01", "2013-12-01", "2014-01-01", "2014-02-01", "2014-03-01", "2014-04-01", "2014-05-01", "2014-06-01", "2014-07-01", "2014-08-01", "2014-09-01", "2014-10-01", "2014-11-01", "2014-12-01")) format(dates_orig, format='%Y%b') [1] "2013Jan" "2013Feb" "2013Mar" "2013Apr" "2013May" "2013Jun" "2013Jul" "2013Aug" "2013Sep" "2013Oct" "2013Nov" "2013Dec" "2014Jan" "2014Feb" "2014Mar" [16] "2014Apr" "2014May" "2014Jun" "2014Jul" "2014Aug" "2014Sep" "2014Oct" "2014Nov" "2014Dec" dates <- as.POSIXlt(dates_orig) # shift Jan and Feb to the previous year dates$year[dates$mon < 2] <- dates$year[dates$mon < 2] - 1 # convert months to seasons (named by first month of season) dates$mon <- (((dates$mon - 2) %/% 3) %% 4) * 3 + 2 format(dates, format='%Y%b') [1] "2012Dec" "2012Dec" "2013Mar" "2013Mar" "2013Mar" "2013Jun" "2013Jun" "2013Jun" "2013Sep" "2013Sep" "2013Sep" "2013Dec" "2013Dec" "2013Dec" "2014Mar" [16] "2014Mar" "2014Mar" "2014Jun" "2014Jun" "2014Jun" "2014Sep" "2014Sep" "2014Sep" "2014Dec" 
  • rbind dataframes в списке списков
  • дубликаты в нескольких столбцах
  • Проблема с geom_text при использовании position_dodge
  • Как указать / таблицу данных по номерам групп из group_by?
  • Как связывать или переписывать векторы разных длин без повторения элементов более коротких векторов?
  • Преобразование кадра данных с столбцом даты в таймсерии
  • Как индексировать векторную последовательность в векторной последовательности
  • Текстовое редактирование с использованием tm-пакета - словосочетание
  • R ggplot2 объединяется с данными шейп-файла и csv для заполнения полигонов
  • Строка ggplot2 дает «geom_path: каждая группа состоит только из одного наблюдения. Вам нужно настроить группу эстетики? "
  • Фильтровать фрейм данных по имени столбца символа (в dplyr)
  • Давайте будем гением компьютера.