Подтвердить что ты не робот

Преобразование года и месяца (формат "yyyy-mm" ) на дату?

У меня есть набор данных, который выглядит так:

Month    count
2009-01  12
2009-02  310
2009-03  2379
2009-04  234
2009-05  14
2009-08  1
2009-09  34
2009-10  2386

Я хочу построить данные (месяцы как значения x и считать как значения y). Поскольку в данных имеются пробелы, я хочу преобразовать информацию за месяц в дату. Я пробовал:

as.Date("2009-03", "%Y-%m")

Но это не сработало. Что не так? Кажется, что as.Date() требует также дня и не может установить стандартное значение для дня? Какая функция решает мою проблему?

4b9b3361

Ответ 1

Попробуйте это. (Здесь мы используем text=Lines, чтобы сохранить пример сам, но на самом деле мы заменили бы его именем файла.)

Lines <- "2009-01  12
2009-02  310
2009-03  2379
2009-04  234
2009-05  14
2009-08  1
2009-09  34
2009-10  2386"

library(zoo)
z <- read.zoo(text = Lines, FUN = as.yearmon)
plot(z)

Ось X не так хороша в использовании этих данных, но если у вас больше данных, это может быть нормально, или вы можете использовать код для причудливой оси X, показанной в разделе примеров ?plot.zoo.

Серия zoo, z, которая создана выше, имеет индекс времени "yearmon" и выглядит следующим образом:

> z
Jan 2009 Feb 2009 Mar 2009 Apr 2009 May 2009 Aug 2009 Sep 2009 Oct 2009 
      12      310     2379      234       14        1       34     2386 

"yearmon" также может использоваться отдельно:

> as.yearmon("2000-03")
[1] "Mar 2000"

Примечание:

  • "yearmon" объекты класса сортируются в порядке календаря.

  • Это будет отображать ежемесячные точки с равными интервалами, которые, скорее всего, нужны; однако, если было бы желательно нанести точки на неравномерно расположенных интервалах, отстоящих пропорционально количеству дней в каждом месяце, тогда преобразуйте индекс z в "Date" class: time(z) <- as.Date(time(z)).

Ответ 2

Поскольку даты соответствуют числовому значению и дате начала, вам действительно нужен день. Если вам действительно нужны ваши данные в формате даты, вы можете просто исправить день до первого числа каждого месяца вручную, вставив его в дату:

month <- "2009-03"
as.Date(paste(month,"-01",sep=""))

Ответ 3

Самое сжатое решение, если вам нужно, чтобы даты были в формате Date:

library(zoo)
month <- "2000-03"
as.Date(as.yearmon(month))
[1] "2000-03-01"

as.Date зафиксирует первый день каждого месяца для объекта yearmon для вас.

Ответ 4

Вы также можете добиться этого с помощью функций parse_date_time или fast_strptime из lubridate -пакета:

> parse_date_time(dates1, "ym")
[1] "2009-01-01 UTC" "2009-02-01 UTC" "2009-03-01 UTC"

> fast_strptime(dates1, "%Y-%m")
[1] "2009-01-01 UTC" "2009-02-01 UTC" "2009-03-01 UTC"

Различие между этими двумя заключается в том, что parse_date_time допускает спецификацию формата в стиле lubridate, тогда как fast_strptime требует того же формата, что и strptime.

Для указания часового пояса вы можете использовать tz -параметр:

> parse_date_time(dates1, "ym", tz = "CET")
[1] "2009-01-01 CET" "2009-02-01 CET" "2009-03-01 CET"

Если у вас есть нерегулярности в данных о дате, вы можете использовать truncated -параметр, чтобы указать, сколько допустимых нарушений:

> parse_date_time(dates2, "ymdHMS", truncated = 3)
[1] "2012-06-01 12:23:00 UTC" "2012-06-01 12:00:00 UTC" "2012-06-01 00:00:00 UTC"

Используемые данные:

dates1 <- c("2009-01","2009-02","2009-03")
dates2 <- c("2012-06-01 12:23","2012-06-01 12",'2012-06-01")

Ответ 5

Используя в любое время пакет:

library(anytime)

anydate("2009-01")
# [1] "2009-01-01"

Ответ 6

В самом деле, как уже упоминалось выше (и в других местах на SO), чтобы преобразовать строку в дату, вам нужна конкретная дата месяца. На странице руководства as.Date():

Если строка даты не указывает дату полностью, возвращаемый ответ может быть системным. Наиболее распространенное поведение - предположить, что отсутствующий год, месяц или день является текущим. Если он задает дату неверно, надежные реализации дадут ошибку, и дата будет указана как NA. К сожалению, некоторые общие реализации (например, glibc) ненадежны и угадывают предполагаемый смысл.

Простым решением было бы вставить дату "01" в каждую дату и использовать strptime(), чтобы указать ее как первый день этого месяца.


Для тех, кто ищет немного больше информации о датах и ​​времени обработки в R:

В R время использует POSIXct и POSIXlt классы и даты, используя класс Date.

Даты сохраняются как количество дней с 1 января 1970 года, а время хранится как количество секунд с 1 января 1970 года.

Итак, например:

d <- as.Date("1971-01-01")
unclass(d)  # one year after 1970-01-01
# [1] 365

pct <- Sys.time()  # in POSIXct
unclass(pct)  # number of seconds since 1970-01-01
# [1] 1450276559
plt <- as.POSIXlt(pct)
up <- unclass(plt)  # up is now a list containing the components of time
names(up)
# [1] "sec"    "min"    "hour"   "mday"   "mon"    "year"   "wday"   "yday"   "isdst"  "zone"  
# [11] "gmtoff"
up$hour
# [1] 9

Выполнять операции по датам и времени:

plt - as.POSIXlt(d)
# Time difference of 16420.61 days

А для обработки дат вы можете использовать strptime() (заимствуя эти примеры на странице руководства):

strptime("20/2/06 11:16:16.683", "%d/%m/%y %H:%M:%OS")
# [1] "2006-02-20 11:16:16 EST"

# And in vectorized form:
dates <- c("1jan1960", "2jan1960", "31mar1960", "30jul1960")
strptime(dates, "%d%b%Y")
# [1] "1960-01-01 EST" "1960-01-02 EST" "1960-03-31 EST" "1960-07-30 EDT"

Ответ 7

Я думаю, что решение @ben-rollert - хорошее решение.

Вам просто нужно быть осторожным, если вы хотите использовать это решение в функции внутри нового пакета.

При разработке пакетов рекомендуется использовать синтаксис packagename::function_name() (см. http://kbroman.org/pkg_primer/pages/depends.html).

В этом случае вы должны использовать версию as.Date(), определенную библиотекой zoo.

Вот пример:

> devtools::session_info()
Session info ----------------------------------------------------------------------------------------------------------------------------------------------------
 setting  value                       
 version  R version 3.3.1 (2016-06-21)
 system   x86_64, linux-gnu           
 ui       RStudio (1.0.35)            
 language (EN)                        
 collate  C                           
 tz       <NA>                        
 date     2016-11-09                  

Packages --------------------------------------------------------------------------------------------------------------------------------------------------------

 package  * version date       source        
 devtools   1.12.0  2016-06-24 CRAN (R 3.3.1)
 digest     0.6.10  2016-08-02 CRAN (R 3.2.3)
 memoise    1.0.0   2016-01-29 CRAN (R 3.2.3)
 withr      1.0.2   2016-06-20 CRAN (R 3.2.3)

> as.Date(zoo::as.yearmon("1989-10", "%Y-%m")) 
Error in as.Date.default(zoo::as.yearmon("1989-10", "%Y-%m")) : 
  do not know how to convert 'zoo::as.yearmon("1989-10", "%Y-%m")' to class "Date"

> zoo::as.Date(zoo::as.yearmon("1989-10", "%Y-%m"))
[1] "1989-10-01"

Итак, если вы разрабатываете пакет, хорошей практикой является использование:

zoo::as.Date(zoo::as.yearmon("1989-10", "%Y-%m"))