As.Date from the format "YYYY.mm"

I have a data frame where the date is stored as a double , for example, 1993.09 1993.10 1993.11 1993.12

I want to convert this to the date format '%Y %m %d' (with days always 1 ).

As far as I understand, as.Date() wants to enter a string. However, for some reason, when I convert my dates to a sapply(dates, as.character) string sapply(dates, as.character) , the zeros after disappearing, effectively converting October to January, resulting in two years a year.

 dates 1993.07 1993.08 1993.09 1993.10 1993.11 1993.12 sapply(dates, as.character) sub("[.]", " ", dates) "1993 07" "1993 08" "1993 09" "1993 1" "1993 11" "1993 12" 

Is there an easier way to convert dates? Or where did I mess up?

dput:

 c(1993.01, 1993.02, 1993.03, 1993.04, 1993.05, 1993.06, 1993.07, 1993.08, 1993.09, 1993.1, 1993.11, 1993.12) 
+7
date r
source share
4 answers

Your problem is that you have something that is a character string, but looks like a number, and you did not take care of it during the import. R does not distinguish between 1993.1 and 1993.10 . Both have the same number. Thus, as.character(1993.10) returns "1993.1" . You need to use the format function to make sure you get two digits after the period, because as.Date "1993.1" and "1993.01" is the same month.

 x <- c(1993.09, 1993.10, 1993.11, 1993.12) as.Date(sprintf("%.2f.01", x), format = "%Y.%m.%d") #[1] "1993-09-01" "1993-10-01" "1993-11-01" "1993-12-01" 

Of course, x should be imported as a symbol to begin with.

+9
source share

If you really want to convert it to the "Date" class using the first month, then Roland's solution seems the most straightforward, but there are other considerations, for example, whether you can use the end of the month or really want to represent year-months using dates, first .

The zoo package has a class "yearmon" that can represent year-months directly without converting them to dates, and also has an as.Date.yearmon method, which has a frac= argument to indicate the fraction of the month path for conversion, if you want a class "Date" .

First make sure dates are character strings. The input in the question shows 1993.10 as one of the input, so we need to make sure that there is a finite zero. (If the inputs are already characters with a trailing zero, this is not a problem. We assumed that the worst case here is a numeric value, so we need to explicitly convert them to characteristic bites with a trailing 0 if necessary.) Now use as.yearmon with format "%Y.%m" . Finally, use as.Date.yearmon to convert to the "Date" class.

Perhaps the biggest advantage of this approach is that we could just leave the result in the "yearmon" class (that is, omit the "as.Date" part, for example as.yearmon(sprintf("%.2f", dates)) ), or if the dates were already character strings, dates.ch , with a trailing 0 in the case of "1993.10" , and then just as.yearmon(dates.ch, "%Y.%m") , which really represents what you’re better, because the day doesn’t really matter, given that it wasn’t in the beginning. "yearmon" objects can be built and sorted in the expected way.

The following is a conversion to the "Date" class using "yearmon" :

 library(zoo) dates <- c(1993.07, 1993.08, 1993.09, 1993.1, 1993.11, 1993.12) # test input as.Date(as.yearmon(sprintf("%.2f", dates), "%Y.%m")) # 1st of month ## [1] "1993-07-01" "1993-08-01" "1993-09-01" "1993-10-01" "1993-11-01" "1993-12-01" as.Date(as.yearmon(sprintf("%.2f", dates), "%Y.%m"), frac = 1) # last of month ## [1] "1993-07-31" "1993-08-31" "1993-09-30" "1993-10-31" "1993-11-30" "1993-12-31" 

or if the test input looks like this:

 dates.ch <- c("1993.07", "1993.08", "1993.09", "1993.10", "1993.11", "1993.12") # input as.Date(as.yearmon(dates.ch, "%Y.%m")) as.Date(as.yearmon(dates.ch, "%Y.%m"), frac = 1) 
+6
source share

Use paste0 to add the day and search for values ​​to format the date with ?strptime . If you are having problems with double-line formatting, you can use formatC :

 txtfield <- c(1993.01, 1993.02, 1993.03, 1993.04, 1993.05, 1993.06, 1993.07, 1993.08, 1993.09, 1993.1, 1993.11, 1993.12) as.Date(paste0(formatC(txtfield, digits=2, format="f"),".01"), "%Y.%m.%d") 

Explanation:

paste0 is an abbreviated version of paste that does not insert spaces between inserted elements.
in formatC , digits indicates the number of digits you want after the decimal place (in our case, we want format 2. to tell R which format number to use, in our case "f" gives the number numbers in the desired xxx.xxx.
as.Date converted to a native R date format with "% Y.% m.% d" defining the full year (4 digits), followed by a dot, followed by a numeric month (2 digits), followed by a dot, which is followed by a numerical day.

results:

 [1] "1993-01-01" "1993-02-01" "1993-03-01" "1993-04-01" "1993-05-01" "1993-06-01" [7] "1993-07-01" "1993-08-01" "1993-09-01" "1993-10-01" "1993-11-01" "1993-12-01" 
+2
source share

You will need to play with the lines. The most obvious way (for me *) would be to "fill" the right side of the values ​​with zeros.

* which is quite a big reservation

 dates <- c(1993.01, 1993.02, 1993.03, 1993.04, 1993.05, 1993.06, 1993.07, 1993.08, 1993.09, 1993.10, 1993.11, 1993.12) library(magrittr) library(stringr) dates %<>% str_pad(width = 7, side = "right", pad = "0") %>% paste0(".01") %>% as.Date(format = "%Y.%m.%d") dates 
0
source share

All Articles