AvdH
AvdH

Reputation: 39

How to use dates in functions in R?

I have a dataframe, with a column of dates, and I would like to make a new column in which the dates are redefined.

I'm using a function to do that, but I have problems defining my dates.

My function has to classify my data into 4 categories: yes, no, NA or invalid

may <- function(x) {
mayfunc <- function (x) { 
  # Classifies date as argument into categories {yes or no} or NA or invalid
  if (is.na(x)) {
    classification <- NA
  } else if (  x <  "2017-05-15" ) {
    classification <- "yes"
  } else if ( "2017-05-15" <= x ) {
    classification <- "no"
  } else {
    classification <- "invalid"
  }
  classification
}
sapply (x, mayfunc)
} 

The results I don't understand

may("lalala")
may(2016-04-13)
may("2016-04-13")
may(2019-01-01)
may("2019-01-01")
may(300)
may(NA)
output: 
lalala 
 "no" --> why not invalid?
[1] "yes" --> correct
2016-04-13 
     "yes" --> correct
[1] "yes"  --> should be  "no"
2019-01-01 
     "no" --> correct
[1] "no" --> why not invalid?
[1] NA

What am I doing wrong?

Upvotes: 0

Views: 159

Answers (1)

Mike
Mike

Reputation: 4400

I think there are a few things I would change. I wouldn't nest the function and also have the sapply in the function call. I would create a function and then call the function in sapply in the global environment.

Here is the function I would use:

mayfun <- function(x){
  # stopifnot is optional - checks if it is a date
  stopifnot(inherits(x, "Date"))
  ifelse(is.na(x), NA,
         ifelse(x < as.Date("2017-05-15"), "yes",
          ifelse(as.Date("2017-05-15") <= x , "no", "invalid")))
}

Then you can use it on single values like this:

#won't work
mayfun("lalala")
#works
mayfun(as.Date("2016-04-13"))
#works
mayfun(as.Date("2019-01-01"))
#won't work
mayfun(300)
#works
mayfun(as.Date(NA))

Or on a column like this:

#silly example but it works
mtcars$newdate <- mayfun(as.Date(mtcars$mpg, origin = "1970-01-01"))

This is more elegant but would overwrite date variables:

#not tested
df[sapply(df, function(x){inherits(x,"Date")})] <- lapply(df[sapply(df, 
                                                  function(x){inherits(x,"Date")})], mayfun)

Upvotes: 1

Related Questions