将年和月("yyyy-mm"格式)转换为日期?

R_U*_*ser 84 posix r date zoo r-faq

我有一个如下所示的数据集:

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
Run Code Online (Sandbox Code Playgroud)

我想绘制数据(月份为x值,计为y值).由于数据存在差距,我想将月份信息转换为日期.我试过了:

as.Date("2009-03", "%Y-%m")
Run Code Online (Sandbox Code Playgroud)

但它没有用.怎么了?似乎as.Date()也需要一天,并且无法设置当天的标准值?哪个功能解决了我的问题?

Sac*_*amp 68

由于日期对应于数值和开始日期,因此您确实需要这一天.如果您确实需要将数据设置为日期格式,则可以通过将日期粘贴到日期来手动将每天固定到每月的第一天:

month <- "2009-03"
as.Date(paste(month,"-01",sep=""))
Run Code Online (Sandbox Code Playgroud)

  • @JBecker你的建议对我不起作用.`> as.Date("2016-01",格式="%Y-%m-01")#[1] NA`.我正在使用R 3.3.1 (17认同)
  • 值得注意的是,您可以在格式化程序中将日期指定为相同,因此您可以执行`as.Date(month,format ='%Y-%m-01')`并获得相同的结果.这种"感觉"比我更好,因为在每个月中指定相同的日期更多的是关于日期格式然后字符串操作,但也许这是无稽之谈. (16认同)

G. *_*eck 55

试试这个.(这里我们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)
Run Code Online (Sandbox Code Playgroud)

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 
Run Code Online (Sandbox Code Playgroud)

"yearmon" 也可以单独使用:

> as.yearmon("2000-03")
[1] "Mar 2000"
Run Code Online (Sandbox Code Playgroud)

注意:

  1. "yearmon" 类对象按日历顺序排序.

  2. 这将以相等的间隔绘制每月点数,这可能是想要的; 但是,如果希望以不相等的间隔绘制点,与每个月的天数成比例,则将指数转换z"Date"类: time(z) <- as.Date(time(z)).


Ben*_*ert 23

如果您需要日期格式为日期格式,则最简洁的解决方案:

library(zoo)
month <- "2000-03"
as.Date(as.yearmon(month))
[1] "2000-03-01"
Run Code Online (Sandbox Code Playgroud)

as.Date 将每个月的第一天修复为一个yearmon对象.


Jaa*_*aap 17

您也可以使用-package中的parse_date_timefast_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"
Run Code Online (Sandbox Code Playgroud)

这两者之间的区别在于parse_date_time允许使用lubridate样式的格式规范,同时fast_strptime需要相同的格式规范strptime.

要指定时区,可以使用tz-parameter:

> parse_date_time(dates1, "ym", tz = "CET")
[1] "2009-01-01 CET" "2009-02-01 CET" "2009-03-01 CET"
Run Code Online (Sandbox Code Playgroud)

如果您的日期时间数据存在不规则性,则可以使用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"
Run Code Online (Sandbox Code Playgroud)

使用数据:

dates1 <- c("2009-01","2009-02","2009-03")
dates2 <- c("2012-06-01 12:23","2012-06-01 12",'2012-06-01")
Run Code Online (Sandbox Code Playgroud)


zx8*_*754 11

使用随时包:

library(anytime)

anydate("2009-01")
# [1] "2009-01-01"
Run Code Online (Sandbox Code Playgroud)

  • 那讲得通.我被模糊地记住了,然后找到了引发评论的内容.从`?strptime`的注释部分:*输入字符串不需要完全指定日期:假设未指定的秒,分或小时为零,未指定的年,月或日是当前的.(但是,如果指定了一个月,则该月的日期必须由%d或%e指定,因为当月的当天不需要在指定的月份有效.)*看起来威震天的答案包含类似的来自`as.Date`的文档. (2认同)
  • 在 1900 年之前的几年里,它不起作用。例如,我尝试了这个 `anytime('1870-01')` (2认同)
  • 唯一对我有用的解决方案!使用anydate()代替anytime() (2认同)

Meg*_*ron 5

事实上,正如上面(以及 SO 上的其他地方)所提到的,为了将字符串转换为日期,您需要一个特定的月份日期。从as.Date()手册页:

如果日期字符串未完全指定日期,则返回的答案可能是系统特定的。最常见的行为是假设缺少的年、月或日是当前的。如果它错误地指定了日期,可靠的实现将给出错误并且日期被报告为 NA。不幸的是,一些常见的实现(例如glibc)是不可靠的并且会猜测预期的含义。

一个简单的解决方案是将日期粘贴"01"到每个日期并用于strptime()将其指示为该月的第一天。


对于那些寻求在 R 中处理日期和时间的更多背景知识的人:

在 R 中,时间使用POSIXct以及POSIXlt类和日期使用Date类。

日期存储为自 1970 年 1 月 1 日以来的天数,时间存储为自 1970 年 1 月 1 日以来的秒数。

因此,例如:

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
Run Code Online (Sandbox Code Playgroud)

要对日期和时间执行操作:

plt - as.POSIXlt(d)
# Time difference of 16420.61 days
Run Code Online (Sandbox Code Playgroud)

要处理日期,您可以使用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"
Run Code Online (Sandbox Code Playgroud)