Converting my dates into a POSIXct class - r

I'm currently working my way through the adehabitatLT package.
I've put my date_time column into characters and named it da:
da<-as.character(dat$date_time)
head(da)
[1] "7/08/2015 0:22" "7/08/2015 0:52" "7/08/2015 1:22" "7/08/2015 1:52" "7/08/2015 2:56" "7/08/2015 3:26"
As you can see my date_time input is a bit non traditional and i think this is where the error occurs, because when i create the class POSIXct:
da<-as.POSIXct(strptime(as.character(dat$date_time),"%d/%m/%y% H:%M:%S"))
It creates the class but i get NA for all my values:
head(da)
[1] NA NA NA NA NA NA
My end objective here is to create an object of the class ltraj (but not only containing the date but the time as well).
Any ideas anyone?
Kind regards,
Sam
da<-as.POSIXct(strptime(as.character(locs$Date),"%y%m%d"))

The format should be modified to
as.POSIXct(strptime(da, "%d/%m/%Y %H:%M"))
Or if month is first followed by day, then change it to "%m/%d/%Y %H:%M"

While parsing tricky date/time formats, it might be useful to use lubridate package by Garrett Grolemund and Hadley Wickham.
In your case, simply do
require(lubridate)
a <- dmy_hm(da)
The separator and the number of digits for day or month or hours etc are automatically parsed.
Find more info here

Related

as.Date giving me NA's

I've tried everything in this thread as.Date returning NA while converting from 'ddmmmyyyy' to try and sort my problem.
I'm using these commands to turn a factor into a date:
cohort$doi <- as.Date(cohort$doi, format= "%Y/%m/%d")
All my dates are currently in the format: YYYY-MM-DD, so as far as I'm aware the above should work
I used this code yesterday to convert all my dates for various variables from a factor to a date. It worked yesterday and everything was fine. Today I opened my script and imported in my data, ran this command and viewed my data but all of the dates now say NA.
I've tried everything from previous threads (I looked at a few more than just the one I linked above) but nothing has so far worked. I'm not sure what to do now
Example of what doi column looks like:
1970-01-01
1970-02-02
1970-03-03
1970-04-04
The column is currently classed as an factor. And when I do the code I used above, the column is defined as a date but all the dates now say NA
Other than closing R and opening it up again for today, I've done nothing else.
If you read the documentation for as.Date you will note the default format is %Y-%d-%m or %Y/%d/%m:
The default formats follow the rules of the ISO 8601 international standard which expresses a day as "2001-02-03".
In your code you have specified your dates are formatted by slashes, but your sample data shows they are formatted in the default format used by as.Date:
doi <- as.factor(c("1970-01-01",
"1970-02-02",
"1970-03-03",
"1970-04-04"))
as.Date(doi) # default format %Y-%m-%d
[1] "1970-01-01" "1970-02-02" "1970-03-03" "1970-04-04"
as.Date(doi, format = "%Y/%m/%d") # incorrect specification of your date format
[1] NA NA NA NA
as.Date("1970/01/01") # also a default format
[1] "1970-01-01"
Note: as.Date accepts character strings, factors, logical NA and objects of classes "POSIXlt" and "POSIXct".

How to make B.C. Date format in R

I have string like 1/1/-2150. How to make Date format from that in R
lubridate back:
library(lubridate)
dmy("1/1/-2150")
[1] "2150-01-01"
as.Date("1/1/-2150",format="%d/%m/%Y")
[1] NA
Now 1/1/-2150 have class character. I need same value but with class Date
Thanks
UPDATE
Something like that, but using lubridate if it possible
minus=as.numeric(dmy("1/1/-2150"))
x<-as.numeric(ymd("0000-1-1"))
dt=as.Date(x*2-minus,origin="1970-01-01")+days(1)
str(dt)
Date[1:1], format: "-2150-01-01"
We need to specify the - in the format
as.Date("1/1/-2150",format="%d/%m/-%Y")
#[1] "2150-01-01"
Unfortunately there aren't any really large R packages tackling this issue (maybe no one has asked). The gregorian package should however, be able to tackle your BCE needs.
gregorian::as_gregorian("-2150-1-1")
[1] "Tuesday January 1, 2151 BCE"

Formatting Unconventional Date

I'm having trouble formatting a list of dates in R. The conventional methods of formatting in R such as as.Date or as.POSIXct don't seem to be working.
I have dates in the format: 1012015
using
as.POSIXct(as.character(data$Start_Date), format = "%m%d%Y")
does not give me an error, but my date returns
"0015-10-12" because the month is not a two digit number.
Is there a way to change this into the correct date format?F
The lubridate package can help with this:
lubridate::mdy(1012015)
[1] "2015-01-01"
The format looks ambiguous but the OP gave two hints:
He is using format = "%m%d%Y" in his own attempt, and
he argues the issue is because the month is not a two digit number
This uses only base R. The %08d specifies a number to be formatted into 8 characters with 0 fill giving in this case "01012015".
as.POSIXct(sprintf("%08d", 1012015), format = "%m%d%Y")
## [1] "2015-01-01 EST"
Note that if you don't have any hours/minutes/seconds it would be less error prone to use "Date" class since then the possibility of subtle time zone errors is eliminated.
as.Date(sprintf("%08d", 1012015), format = "%m%d%Y")
## [1] "2015-01-01"

How can I change character class date variables to POSIXlt class when there are multiple date formats?

I'm struggling with converting character class dates of many different format types (e.g., yyyy/mm/dd; mm/dd/yyyy; yyyy-mm-dd; mm-dd-yyyy; yy-mm-dd; mm-dd-yy; etc.) to POSIXlt class. Ideally, I would like to convert all birth_dates to POSIXlt class with yyyy/mm/dd format (see sample data below). Is there any simple way to do this in R?:
id birth_date start_date age
102 08/09/1993 2013/09/01 20
103 1995-02-21 2013/09/01 18
104 01-15-94 2013/09/01 19
105 88-12-30 2013/09/01 24
Here is what I have been doing thus far. Unfortunately, this doesn't seem to work (I wind up with more NAs than there should be) given all of the different ways in which the original date is formatted:
library(lubridate)
data$birth_date1<-as.Date(data$birth_date,format="%Y-%m-%d") #Convert character class to date class
data$birth_date2<-ymd(swc3$birth_date1) #Convert date class to POSIXlt class using lubridate pkg
That's horrible. Could be worse though. At least there are delimiters in there, like "-" and "/".
Short Answer
Yes, there's an easy way to parse that in R. Apply parse_date_time() separately to each birth date, giving it a decent orders list to chose from, and carefully set the order of the guesses. You'll need to convert the "integer-time" to a useful time when you're done.
See the Long Answer for details.
Long Answer
This is why the lubridate package has parse_date_time(). But there are problems. Let's see:
require(lubridate)
# WRONG! doesn't work as intended.
as.Date(
parse_date_time(data$birth_date,
orders=c("ymd", "mdy", "mdY", "Ymd")
)
)
[1] "1993-08-09" "1995-02-21" "1994-01-15" "0088-12-30"
That looks great, except for the last one. What's going on?
parse_date_time() is selecting a "best fit" set of orders and formats to use when parsing the dates, and the last element is the odd one out.
To make this work as intended, you'll need to apply parse_date_time() one-by-one to each date, because each date format was apparently selected more-or-less at random. This will be slower, but it will give more useful answers.
# RIGHT. Some conversion of results required.
parsed <- sapply(data[,"birth_date"],
parse_date_time,
orders=c("ymd", "mdy", "mdY", "Ymd") )
parsed
08/09/1993 1995-02-21 01-15-94 88-12-30
744854400 793324800 758592000 599443200
Ok, those look like Unix-time integers, which are the unclass()'d version of what parse_date_time() produces. And none are negative, so they must all have happened after 1970. This is encouraging. Convert:
# Conversion of results
parsed <- as.POSIXct(parsed, origin="1970-01-01", tz = "GMT")
as.Date(parsed)
08/09/1993 1995-02-21 01-15-94 88-12-30
"1993-08-09" "1995-02-21" "1994-01-15" "1988-12-30"
lubridate and parse_date_time() are very good at what they do.
Since you asked for POSIXlt, not Date types:
as.POSIXlt(parsed)
08/09/1993 1995-02-21
"1993-08-09 10:00:00 AEST" "1995-02-21 11:00:00 AEDT"
01-15-94 88-12-30
"1994-01-15 11:00:00 AEDT" "1988-12-30 11:00:00 AEDT"
Though I personally prefer only having dates when the actual time isn't important; these are assumed to be all happening at midnight UTC, and are converted to my time zone (Eastern Australia).

How to convert ordinal date day-month-year format using R

I have log files where the date is mentioned in the ordinal date format.
wikipedia page for ordinal date
i.e 14273 implies 273'rd day of 2014 so 14273 is 30-Sep-2014.
is there a function in R to convert ordinal date (14273) to (30-Sep-2014).
Tried the date package but didn come across a function that would do this.
Try as.Date with the indicated format:
as.Date(sprintf("%05d", 14273), format = "%y%j")
## [1] "2014-09-30"
Notes
For more information see ?strptime [link]
The 273 part is sometimes referred to as the day of the year (as opposed to the day of the month) or the day number or the julian day relative to the beginning of the year.
If the input were a character string of the form yyjjj (rather than numeric) then as.Date(x, format = "%y%j") will do.
Update Have updated to also handle years with one digit as per comments.
Data example
x<-as.character(c("14273", "09001", "07031", "01033"))
Data conversion
x1<-substr(x, start=0, stop=2)
x2<-substr(x, start=3, stop=5)
x3<-format(strptime(x2, format="%j"), format="%m-%d")
date<-as.Date(paste(x3, x1, sep="-"), format="%m-%d-%y")
You can use lubridate package as follows:
>library(lubridate)
# Create a template date object
>date <- as.POSIXlt("2009-02-10")
# Update the date using
> update(date, year=2014, yday=273)
[1] "2014-09-30 JST"

Resources