R timeDate drops time in coersion - r

I have dates of the format: "2/9/2016 21:16"
When I attempt to coerce them to a timeDate, I receive the result: [1] [2016-02-03]
I would prefer to not have to write my own string manipulation, but I can and already have, but there has to be a better way. I have a dataframe and I am attempting to do the following:
restData2 <- restData %>%
mutate(year = year(as.timeDate(Date)),
month = month(as.timeDate(Date)),
day = day(as.timeDate(Date)),
timeCategory = converToTimeCategory(Date)
)
Note, that day is not a function in timeDate either. Day of Week and Day of year exist, I need Day of Month.
The data exists in a data frame. The data is basic transaction data.

David, you are confused. R differentiates between internal representation and actual formated display. For all types.
And there is (once again) no need for timeDate, lubridate, or any other wrapper:
R> intxt <- c("2/9/2016 21:16", "2/11/2016 22:23")
R> parsed <- as.POSIXct(intxt, format="%d/%m/%Y %H:%M")
R> parsed
[1] "2016-09-02 21:16:00 CDT" "2016-11-02 22:23:00 CDT"
R> format(parsed, "%d %b %Y at %H:%M")
[1] "02 Sep 2016 at 21:16" "02 Nov 2016 at 22:23"
R>
Here we parse a datetime object into the standard POSIXct, specifying a format. Which can be day-month or month-day; here I picked the former.
Given the parsed object, I first show the default display, and then a custom format string.
Lastly, if you must, you can also convert to timeDate:
R> library(timeDate)
R> as.timeDate(parsed)
GMT
[1] [2016-09-03 02:16:00] [2016-11-03 03:23:00]
R>
Not the timezone adjustment from my local (Central) time.

Related

Converting date from 2019-07-04 14:01 +0000 to MM/dd/yyyy format

I am trying to the date format 2019-07-04 14:01 +0000 to mm/dd/yyyy format.
I am using this:
as.Date(strptime(d <- Twitter$time, "%b %d %Y %H:%M %p"))
I've also tried:
ymd_hms(Twitter$time)
However it returns NA values. Is there any way to convert this format to MM/dd/yyyy in R?
As we are not interested in the time component convert the column to Date class with as.Date (here the format is not required as the input is in the default format mode) and use format to change the format
format(as.Date(str1), "%m/%d/%Y")
#[1] "07/04/2019"
data
str1 <- "2019-07-04 14:01 +0000"
There are always two steps: parse, and format.
You can use as.Date() as shown or anydate() from the anytime package (which will also work for different input formats as shown here):
R> inp <- anytime::anydate(c("2019-07-04 14:01 +0000", "04-Jul-2019 14:02"))
R> inp
[1] "2019-07-04" "2019-07-04"
R> format(inp, "%m/%d/%Y")
[1] "07/04/2019" "07/04/2019"
R>

setting column to datetime in R

The date in my dataset is like this: 20130501000000 and I'm trying to convert this to a better datetime format in R
data1$date <- as.Date(data1$date, format = "%Y-%m-%s-%h-%m-%s")
However, I get an error for needing an origin. After I put the very first cell under date in as origin, it converts every cell under date to N/A. Is this right or should I try as.POSIXct()?
That is a somewhat degenerate format, but the anytime() and anydate() functions of the anytime package can help you, without requiring any explicit format strings:
R> anytime("20130501000000") ## returns POSIXct
[1] "2013-05-01 CDT"
R> anydate("20130501000000") ## returns Date
[1] "2013-05-01"
R>
Not that we parse from character representation here -- parsing from numeric would be wrong as we use a conflicting heuristic to make sense of dates stored a numeric values.
So here your code would just become
data1$data <- anytime::anydate(data1$date)
provided data1$date is in character, else wrap one as.character() around it.
Lastly, if you actually want Datetime rather than Date (as per your title), don't use anydate() but anytime().
Before I write my answer, I would like to say that the format argument should be the format that your string is in. Therefore, if you have "20130501000000", you have to use (you don't have - between each component of your date in the string format):
as.Date("20130501000000", format = "%Y%m%d%H%M%S")
# [1] "2013-05-01"
which works just fine, does not produce any error, and will return an object of class Date:
as.Date("20130501000000", format = "%Y%m%d%H%M%S") |> class()
# [1] "Date"
Therefore, I think your issue is more of a formatting and not origin of the date.
Now to my detailed answer:
As far as I know and can understand, the as.Date() will convert it to "date", so if you want the time part of the string as well, you have to use as.POSIXct():
as.POSIXct("20130501000000", format = "%Y%m%d%H%M%S")
# [1] "2013-05-01 EEST"
as.POSIXct("20130501000000", format = "%Y%m%d%H%M%S") |> class()
# [1] "POSIXct" "POSIXt"
Note that the timezone is EEST which is my local timezone, if you want to define the timezone, you have to define it. For example to set the timezone to UTC:
as.POSIXct("20130501000000", format = "%Y%m%d%H%M%S", tz = "UTC")
# [1] "2013-05-01 UTC"
using the as.POSIXct() you can do arithmetic with the object:
times <- c("20130501000000",
"20130501035001") # added 03:50:01 to the first element
class(times)
# [1] "character"
times <- as.POSIXct(times, format = "%Y%m%d%H%M%S", tz = "UTC")
class(times)
# [1] "POSIXct" "POSIXt"
times[2] - times[1]
# Time difference of 3.833611 hours

Dealing with date-time string that has day of the week

I have a date-time string that has day of the week and some meta-data in the string.
d <- "Fri, 14 Jul 2000 06:59:00 -0700 (PDT)"
I need to convert it into a date-time object (e.g. I have a column of these in a data.table) for further analysis. I have dealt with this using regexes to strip off meta-data from the string. Is there a better approach?
What I have is:
m <- regexpr("^\\w+,\\s+", d, perl=TRUE)
regmatches(d, m)
m <- regexpr("\\s-?\\d+\\s\\(\\w+\\)$", d, perl=TRUE)
regmatches(d, m)
ds <- sub("^\\w+,\\s+", "", d)
ds <- sub("\\s-?\\d+\\s\\(\\w+\\)$", "", ds)
Now I can convert this to date-time objects of class Date, Posixlt or Posixct for use in analysis.
dd <- strptime(ds, format="%d %b %Y %H:%M:%S")
dd <- as.Date(ds, format="%d %b %Y %H:%M:%S")
dd <- as.POSIXct(ds, format="%d %b %Y %H:%M:%S")
I wrote the anytime package to help with (among other things) these silly format strings -- so it heuristically just tries a number of them (and focuses on sane ones).
The input you have here qualifies (and is in fact a pretty common form):
R> anytime("Fri, 14 Jul 2000 06:59:00 -0700 (PDT)")
[1] "2000-07-14 06:59:00 CDT"
R>
We do not currently try to capture the timezone offset information at the end, so you have to deal with that after the fact. The display is in CDT which is my local timezone.
There is some more information about anytime on its webpage.
assuming the format of string is going to be constant across your data :
time = trimws(unlist(strsplit(d, "[,-]"))[2])
#[1] "14 Jul 2000 06:59:00"
tz = unlist(strsplit(d, "[,-]"))[3]
tz = gsub("[^A-Z]", "", tz)
#[1] "PDT"
> as.Date(time, format = "%d %b %Y")
[1] "2000-07-14"
> as.POSIXct(time, format = "%d %b %Y %H:%M:%S") #specify th etimezone with tz
[1] "2000-07-14 06:59:00 IST"

date conversion from any fromat [duplicate]

I am reading a date value from csv file.So the format will vary according to the date format of csv. How can I convert any date string to dd-mm-yyy HH:mm:ss ?
EDIT :
The input format are :
dd/mm/yyyy HH:mm:ss
dd/mm/yyyy
dd-mm-yyyy HH:mm:ss
dd-mm-yyyy
mm-dd-yyyy HH:mm:ss
mm-dd-yyyy
mm/dd/yyyy
yyyy-mm-dd HH:mm:ss
yyyy-mm-dd
I need to convert all these formats to dd-mm-yyyy HH:mm:ss
See the anytime package whose anytime function does just that -- and without requiring a format string:
> inputs <- c("12/07/2017 10:11:12", "12/07/2017", "12-07-2017 10:11:12",
+ "07-12-2017", "2017-12-07 10:11:12", "2017-12-07")
> library(anytime)
> anytime(inputs)
[1] "2017-12-07 10:11:12 CST" "2017-12-07 00:00:00 CST"
[3] "2017-12-07 10:11:12 CST" "2017-07-12 00:00:00 CDT"
[5] "2017-12-07 10:11:12 CST" "2017-12-07 00:00:00 CST"
>
However, your requirement of accepting both d-m-y and m-d-y is not satisfiable. So you need to make a choice and supply an explicit format here.
In general, I highly recommend avoiding the ambiguity and sticking to y-m-d ISO formats. As a convenience to stubborn North American habits, anytime and anydata also accept m-d-y ordering but it is dangerous.
Again, only you can tell if 3-4-5 is April 3rd or March 4th, and you need to specify that.
as.Date() converts a string into a Date object. You will need to adapt its format parameter to the specific format your csv has.
Try "lubridate" package. Here A_1.csv has both formats.
Data <-read.csv("Al_1.csv") # import data
str(Data)
a = NULL # create a null object
library(lubridate)
a$Date <- mdy_hm(Data$Date) # store dd/mm/yyyy HH:mm:ss objects here
a$Price <- Data$Price # get respective values(it could by any other column)
b = NULL
b$Date <- mdy(Data$Date)
b$Price <- Data$Price
a <- as.data.frame(a)
b <- as.data.frame(b)
a <- a[is.na(a$Date)==FALSE,] # those with NA had diffrent formats remove it
b <- b[is.na(b$Date)==FALSE,]
b$Date <- as.POSIXlt(b$Date)# change your other format also to UTC
x <- rbind(a,b)
str(x)
x <- ts(x)

Date in the form: 20120405

Apologies for the simple question, but I can't find help for this type of date.
April 5th, 2012 is saved as numeric as "20120405"
How can I convert a vector of such values into usable dates?
You just need the as.Date function:
R> x = "20120405"
R> as.Date(x, "%Y%m%d")
[1] "2012-04-05"
Look at the help file: ?as.Date, but essentially
%Y means year in the form 2012, use %y for 12.
%m is the month.
%d the day.
If your date had separators, say, 2012-04-05, then use something like: %Y-%m-%d. Alternatively, you can use:
R> strptime(x, "%Y%m%d")
[1] "2012-04-05"
In particular, you can pass vectors of dates to these functions, so:
R> y = c("20120405", "20121212")
R> as.Date(y, "%Y%m%d")
[1] "2012-04-05" "2012-12-12"
like this,
(foo <- as.Date("20120405", "%Y%m%d"))
# "2012-04-05"
and maybe you want to format to get the month printed out
format(foo, "%Y %b %d")
# "2012 Apr 05"
You could take a look at this page
With strptime you can convert it to POSIXlt class and with as.Date you can convert it to a Date class using format "%Y%m%d":
strptime( "20120405",format="%Y%m%d")
[1] "2012-04-05"
as.Date( "20120405",format="%Y%m%d")
[1] "2012-04-05"
Edit:
It is not really clear if you have character "20120405" or numeric 20120405. In the latter case you have to convert to character first with as.character(20120405)
You could also use the lubridate package:
library(lubridate)
ymd("20120405")

Resources