Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R apply function returns numeric value on date variables

I have a R dataframe which have sequence of dates. I want to create a dataframe from the existing one which consists of one month prior dates. For example let x be the initial dataframe

x = data.frame(dt = c("28/02/2000","29/02/2000","1/03/2000","02/03/2000"))

My required dataframe y would be

y = c("28/01/2000","29/01/2000","1/02/2000","02/02/2000")

The list is quite big so I don't want looping. I have created a inline function which works fine when I give individual dates.

datefun <- function(x) seq(as.Date(strptime(x,format = "%d/%m/%Y")), length =2, by = "-1 month")[2]

datefun("28/02/2000") gives "28/01/2000" as an output

But while I use it inside R apply it gives random numerical values.

apply(x,1,function(x) datefun(x))

The output for this is

[1] 10984 10985 10988 10989

I don't know from where these numbers are getting generated, am I missing something.

like image 808
amitbisai Avatar asked Sep 22 '17 06:09

amitbisai


People also ask

Are dates numeric in R?

Date objects in RDate objects are stored in R as integer values, allowing for dates to be compared and manipulated as you would a numeric vector.

How do you set a variable in R date?

To create a Date object from a simple character string in R, you can use the as. Date() function. The character string has to obey a format that can be defined using a set of symbols (the examples correspond to 13 January, 1982): %Y : 4-digit year (1982)

What is POSIXct format in R?

POSIXct stores date and time in seconds with the number of seconds beginning at 1 January 1970. Negative numbers are used to store dates prior to 1970. Thus, the POSIXct format stores each date and time a single value in units of seconds. Storing the data this way, optimizes use in data.


2 Answers

You should not use apply since the result will be returned as a matrix. Matrices in R cannot store values of class Date. You have to use lapply instead. This returns a list of results. These results can be combined with Reduce and c to create a Date vector.

Reduce(c, lapply(x$dt, datefun))
# [1] "2000-01-28" "2000-01-29" "2000-02-01" "2000-02-02"
like image 152
Sven Hohenstein Avatar answered Sep 28 '22 08:09

Sven Hohenstein


I believe that R internally is storing your dates as time elapsed since the UNIX epoch, which is January 1, 1970. You can easily view your updated dates as readable strings using as.Date with an apporpriate origin, e.g.

y <- apply(x,1,function(x) datefun(x))
as.Date(y, origin='1970-01-01')

[1] "2000-01-28" "2000-01-29" "2000-02-01" "2000-02-02"

The gist here is that the numerical output you saw perhaps misled you into thinking that your date information were somehow lost. To the contrary, the dates are stored in a numerical format, and it is up to you to tell R how you want to view that information as dates.

Demo

like image 20
Tim Biegeleisen Avatar answered Sep 28 '22 08:09

Tim Biegeleisen