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

r date posix zoo r-faq

99296 просмотра

7 ответа

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

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

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

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

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

Автор: R_User Источник Размещён: 29.07.2019 08:35

Ответы (7)


53 плюса

Решение

Попробуй это. (Здесь мы используем, 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.

Ряд зоопарка 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"

Замечания:

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

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

Автор: G. Grothendieck Размещён: 05.06.2011 12:58

67 плюса

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

month <- "2009-03"
as.Date(paste(month,"-01",sep=""))
Автор: Sacha Epskamp Размещён: 05.06.2011 12:46

23 плюса

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

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

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

Автор: Ben Rollert Размещён: 07.02.2014 01:50

15 плюса

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

> 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-para:

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

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

> 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")
Автор: Jaap Размещён: 25.06.2017 10:15

10 плюса

Используя пакет anytime :

library(anytime)

anydate("2009-01")
# [1] "2009-01-01"
Автор: zx8754 Размещён: 07.03.2017 09:29

4 плюса

Действительно, как было упомянуто выше (и в других местах 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"
Автор: Megatron Размещён: 17.12.2015 04:28

0 плюса

Я думаю, что решение @ 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"))
Автор: PAC Размещён: 09.11.2016 01:31
Вопросы из категории :
32x32