I have an integer which I want to convert to class Date. I assume I first need to convert it to a string, but how?
My attempt:
v <- 20081101
date <- as.Date(v, format("%Y%m%d"))
Error in charToDate(x) : character string is not in a standard
unambiguous format
Using paste() works, but is that really the correct way to do the conversion?
date <- as.Date(paste(v), format("%Y%m%d"))
date
[1] "2008-11-01"
class(date)
# [1] "Date"
as.character() would be the general way rather than use paste() for its side effect
> v <- 20081101
> date <- as.Date(as.character(v), format = "%Y%m%d")
> date
[1] "2008-11-01"
(I presume this is a simple example and something like this:
v <- "20081101"
isn't possible?)
Another way to get the same result:
date <- strptime(v,format="%Y%m%d")
You can use ymd from lubridate
lubridate::ymd(v)
#[1] "2008-11-01"
Or anytime::anydate
anytime::anydate(v)
#[1] "2008-11-01"
Related
I am working with an external package that's converting columns of a dataframe with the lubridate date type Date into numeric type. (Confirmed by running as.numeric() on the columns).
I'm wondering if there's a way to convert it back?
For example, if I have the date "O1-01-2021" then running as.numeric on it returns -719143. How can I turn that back into "O1-01-2021" ?
Note that Date class is part of base R, not lubridate.
You probably assumed that the data was year/month/day by mistake. Using base R to eliminate lubridate as a problem we can replicate the question's result like this:
as.numeric(as.Date("01-01-2021", "%Y-%m-%d"))
## [1] -719143
Had we used day/month/year we would have gotten:
as.numeric(as.Date("01-01-2021", "%d-%m-%Y"))
## [1] 18628
or using lubridate
library(lubridate)
as.numeric(dmy("01-01-2021"))
## [1] 18628
It would be best if you fix the mistake that resulted in -719143 but if you don't control that and are faced with an input of
-719143 and want to get as.Date("2021-01-01") as the output then:
# input x is numeric; result is Date class
fixup <- function(x) as.Date(format(.Date(x), "%y-%m-%d"), "%d-%m-%y")
fixup(-719143)
## [1] "2020-01-01"
Note that we can't tell from the question whether 01-01-2020 is supposed to represent day-month-year or month-day-year so we assumed the first but if it is to represent the second then it should be obvious at this point how to proceed.
EDIT #2: It looks like the original data is being parsed as Jan 20, year 1, which might happen if the year-month-day columns were jumbled while being parsed:
as.numeric(as.Date("01-01-2021", format = "%Y-%m-%d", origin = "1970-01-01"))
[1] -719143
as.numeric(as.Date("0001-01-20", origin = "1970-01-01"))
[1] -719143
Is there a way to share an example of the raw data as you have it? e.g. dput(MY_DATA[1:10, DATE_COL])
EDIT: -719143 is about 1970 years of days, which can't be a coincidence, given that many date/time formats use 1970 as a baseline. I wonder if 01-01-2021 is being interpreted as the numeric formula equal to -2021 and so we're looking at perhaps -2021 seconds/days/[?] before year zero, which would be about -1970 years before the epoch...
-719143/(365)
[1] -1970.255
For instance, we can get something close with:
as.numeric(as.Date("0000-01-01", origin = "1970-01-01"))
[1] -719528
Original answer:
R treats a string describing a date as text:
x <- "01-01-2021"
class(x)
[1] "character"
We can convert it to a Date data type using these two equivalent commands:
base_dt <- as.Date(x, "%m-%d-%Y") # base R version
lubridt <- lubridate::mdy(x) # convenience lubridate function
identical(base_dt, lubridt)
[1] TRUE
Under the hood, a Date object in R is a numeric value with a flag telling R it's a date:
> typeof(lubridt) # What general type of data is it?
[1] "double" # --> numeric, stored as a double
> as.numeric(lubridt)
[1] 18628
> class(lubridt) # Does it have any special class attributes?
[1] "Date" # --> yes, it's a Date
> dput(lubridt) # How would we construct it from scratch?
structure(18628, class = "Date") # --> by giving 18628 a Date attribute
In R, a Date is encoded as the number of days since 1970 began:
> as.Date("1970-01-1") + as.numeric(lubridt)
[1] "2021-01-01"
We could convert it back to the original text using:
format(base_dt, "%m-%d-%Y")
[1] "01-01-2021"
identical(x, format(base_dt, "%m-%d-%Y"))
[1] TRUE
I am trying to convert the following numbers to dates in R:
Use as.Date with the correct format mask:
dates <- c(19801231, 19810130, 19810227)
as.Date(as.character(dates), format="%Y%m%d")
[1] "1980-12-31" "1981-01-30" "1981-02-27"
Note that if your Names.Date column already be text, then you can skip the extra conversion and just use:
as.Date(dates, format="%Y%m%d")
You can use lubridate package.
> library(lubridate)
> Names.Date <- c(19810130, 19810227, 19810331)
> Names.Date
[1] 19810130 19810227 19810331
> ymd(Names.Date)
[1] "1981-01-30" "1981-02-27" "1981-03-31"
>
An option with anydate
library(anytime)
anydate(dates)
#[1] "1980-12-31" "1981-01-30" "1981-02-27"
data
dates <- c(19801231, 19810130, 19810227)
I would like to convert a YYYYMM-integer to a Date without converting it to character (=is there a mdy-function like in SAS?). I would like to replace this code:
dateint<-201511
datestr<-paste(toString(dateint,length=8),'01')
date<-as.Date(datestr,'%Y%m%d')
print(date)
class(date)
with a working version of this. If possible the resulting class should be a date too:
year<-dateint %% 100
month<-floor(dateint/100)
date2<-ISOdate(year,month,1) # I can't make this work ..
print(date2)
class(date2)
Thanks & kind regards
The package lubridate has a function ymd, which accepts numeric input:
> library(lubridate)
> ymd(20151101)
[1] "2015-11-01 UTC"
You need however to add the day at the end.
Using R, I want to be able to turn a date in format "2014-12-31" to an integer of 20141231, for the purpose of creating a serial number.
My aim is simply to be able to complete the REVERSE of this user question (Turning an integer string date into an actual date).
Appreciate any help provided.
Simply format the Date in that way, then call as.integer on the result.
R> as.integer(format(Sys.Date(), "%Y%m%d"))
[1] 20151008
If your date isn't a Date, and is a character string: either convert it to a Date first, or remove the "-" before calling as.integer.
R> dateString <- "2014-12-31"
R> as.integer(format(as.Date(dateString), "%Y%m%d"))
[1] 20141231
R> as.integer(gsub("-", "", dateString))
[1] 20141231
Or if you already have character dates:
a <- "2015-03-15"
as.integer(gsub(pattern = "-", replacement="", x = a))
#[1] 20150315
I would like to convert these dates with format YYYYMMDD to a Date class.
dates <- data.frame(Date = c("20130707", "20130706", "20130705", "20130704"))
I tried:
dates <- as.Date(dates, "%Y%m%d")
And I get the following error:
Error in as.Date.default(dates, "%Y%m%d") :
do not know how to convert 'dates' to class "Date"
What would be the correct way to set this format?
You need to provide the Date column, not the entire data.frame.
R> as.Date(dates[["Date"]], "%Y%m%d")
[1] "2013-07-07" "2013-07-06" "2013-07-05" "2013-07-04"
An extra conversion to characters works for me:
dates<-as.Date(as.character(dates),format="%Y%m%d")
Without the conversion the following error occurs:
dates<-as.Date(dates,format="%Y%m%d")
Error in as.Date.numeric(dates, format = "%Y%m%d") :
'origin' must be supplied
Different error but this might help, works for POSIXct too, paste date and hours, format %Y%m%d%H
Classic R:
> start_numeric <- as.Date('20170215', format = '%Y%m%d');
> start_numeric
[1] "2017-02-15"
> format(start_numeric, "%Y%m%d")
[1] "20170215"
Use the lubridate package for an easy conversion:
date_test <- data.frame(Date = c("20130707", "20130706", "20130705", "20130704"))
date_test$Date <- ymd(date_test$Date)
date_test
Date
1 2013-07-07
2 2013-07-06
3 2013-07-05
4 2013-07-04
Instead of using brackets, you can use variable name:
dates <- data.frame(Date = c("20130707", "20130706", "20130705", "20130704"))
as.Date(dates$Date, "%Y%m%d")
[1] "2013-07-07" "2013-07-06" "2013-07-05" "2013-07-04"