Converting year and month (“yyyy-mm” format) to a

2018-12-31 01:34发布

I have a dataset that looks like this:

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

I want to plot the data (months as x values and counts as y values). Since there are gaps in the data, I want to convert the Information for the Month into a date. I tried:

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

But it did not work. Whats wrong? It seems that as.Date() requires also a day and is not able to set a standard value for the day? Which function solves my problem?

7条回答
泪湿衣
2楼-- · 2018-12-31 02:03

I think @ben-rollert's solution is a good solution.

You just have to be careful if you want to use this solution in a function inside a new package.

When developping packages, it's recommended to use the syntaxe packagename::function_name() (see http://kbroman.org/pkg_primer/pages/depends.html).

In this case, you have to use the version of as.Date() defined by the zoo library.

Here is an example :

> 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"

So if you're developping a package, the good practice is to use :

zoo::as.Date(zoo::as.yearmon("1989-10", "%Y-%m"))
查看更多
其实,你不懂
3楼-- · 2018-12-31 02:07

You could also achieve this with the parse_date_time or fast_strptime functions from the 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"

The difference between those two is that parse_date_time allows for lubridate-style format specification, while fast_strptime requires the same format specification as strptime.

For specifying the timezone, you can use the tz-parameter:

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

When you have irregularities in your date-time data, you can use the truncated-parameter to specify how many irregularities are allowed:

> 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"

Used data:

dates1 <- c("2009-01","2009-02","2009-03")
dates2 <- c("2012-06-01 12:23","2012-06-01 12",'2012-06-01")
查看更多
时光乱了年华
4楼-- · 2018-12-31 02:10

Using anytime package:

library(anytime)

anydate("2009-01")
# [1] "2009-01-01"
查看更多
伤终究还是伤i
5楼-- · 2018-12-31 02:16

Since dates correspond to a numeric value and a starting date, you indeed need the day. If you really need your data to be in Date format, you can just fix the day to the first of each month manually by pasting it to the date:

month <- "2009-03"
as.Date(paste(month,"-01",sep=""))
查看更多
孤独寂梦人
6楼-- · 2018-12-31 02:20

Try this. (Here we use text=Lines to keep the example self contained but in reality we would replace it with the file name.)

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)

The X axis is not so pretty with this data but if you have more data in reality it might be ok or you can use the code for a fancy X axis shown in the examples section of ?plot.zoo .

The zoo series, z, that is created above has a "yearmon" time index and looks like this:

> 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" can be used alone as well:

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

Note:

  1. "yearmon" class objects sort in calendar order.

  2. This will plot the monthly points at equally spaced intervals which is likely what is wanted; however, if it were desired to plot the points at unequally spaced intervals spaced in proportion to the number of days in each month then convert the index of z to "Date" class: time(z) <- as.Date(time(z)) .

查看更多
墨雨无痕
7楼-- · 2018-12-31 02:24

The most concise solution if you need the dates to be in Date format:

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

as.Date will fix the first day of each month to a yearmon object for you.

查看更多
登录 后发表回答