Giter VIP home page Giter VIP logo

Comments (7)

garrettgman avatar garrettgman commented on August 21, 2024

I got it to work for both by setting things up as
"+.duration" <- "+" <- function(e1, e2){
if(!is.POSIXt(e1) && is.duration(e2)) e1 <- as.duration(e1)
if(!is.POSIXt(e2) && is.duration(e1)) e2 <- as.duration(e2)
if (is.duration(e1) && is.duration(e2))
add_duration_to_duration(e1, e2)
else if (is.duration(e1) && is.POSIXt(e2))
add_duration_to_date(e2, e1)
else if (is.duration(e2) && is.POSIXt(e1))
add_duration_to_date(e1, e2)
else {
base::'+'(e1, e2)
}
}

just want to verify with you that this isn't a bad idea before I close this issue. (If a user then loads a package that uses a similar approach, '+' will be rewritten and '+.duration' and '+' will give incompatible methods. But on the otherhand, '+.duration' is compatible with everything until this happens.

from lubridate.

hadley avatar hadley commented on August 21, 2024

Try +.duration <- +.POSIXt <- .difftime and then let me know what doesn't work.

from lubridate.

garrettgman avatar garrettgman commented on August 21, 2024
  1. if we leave the code as it is but replace +.duration <- + <- with +.duration <- +.POSIXt <- .difftime, adding two difftimes yields:

Error: evaluation nested too deeply: infinite recursion / options(expressions=)?

The same is true for adding two POSIXt dates (this should produce an error, but a different one)

  1. If we expand the code to:
    "+.duration" <- "+.POSIXt" <- "+.difftime" <- function(e1, e2){
       ...
       else if (is.difftime(e1) && is.difftime(e2))
          base::Ops.difftime(e1, e2)
       else {
          base::'+'(e1, e2)
       }
    }  
    
    adding two difftimes yields

Error in switch(.Generic, < = , > = , == = , != = , <= = , >= = TRUE, :
object '.Generic' not found

from lubridate.

garrettgman avatar garrettgman commented on August 21, 2024

The following code solves all these issues except for the minor issue noted below:

"+.duration" <- "+.POSIXt" <- "+.difftime" <- function(e1, e2){
if(!is.POSIXt(e1) && is.duration(e2)) e1 <- as.duration(e1)
if(!is.POSIXt(e2) && is.duration(e1)) e2 <- as.duration(e2)
if (is.duration(e1) && is.duration(e2))
add_duration_to_duration(e1, e2)
else if (is.duration(e1) && is.POSIXt(e2))
add_duration_to_date(e2, e1)
else if (is.duration(e2) && is.POSIXt(e1))
add_duration_to_date(e1, e2)
else if (is.POSIXt(e1) && is.POSIXt(e2))
stop("binary '+' is not defined for "POSIXt" objects")
else if (is.POSIXt(e1) || is.POSIXt(e2))
base::'+.POSIXt'(e1,e2)
else if (is.difftime(e1) && is.difftime(e2))
make_difftime(as.duration(e1) + as.duration(e2))
else if (is.difftime(e1)){
e2 <- structure(e2, units = units(e1), class = "difftime")
make_difftime(as.duration(e1) + e2)
}
else if (is.difftime(e2)){
e1 <- structure(e1, units = units(e2), class = "difftime")
make_difftime(as.duration(e2) + e1)
}
else
base::'+'(e1, e2)

}

make_difftime <- function (dur) {
if (dur$months != 0)
stop("difftime does not support non-uniform durations (months)")
if (dur$seconds < 60)
units <- "secs"
else if (dur$seconds < 3600)
units <- "mins"
else if (dur$seconds < 86400)
units <- "hours"
else units <- "days"

switch(units, secs = structure(dur$seconds, units = "secs", class = "difftime"), 
    mins = structure(dur$seconds/60, units = "mins", class = "difftime"), 
    hours = structure(dur$seconds/3600, units = "hours", class = "difftime"), 
    days = structure(dur$seconds/86400, units = "days", class = "difftime"), 
    weeks = structure(dur$seconds/(7 * 86400), units = "weeks", class = "difftime"))

}

Minor issue: I don't know why, but R seems to disobey the order rule when operating with difftimes, soif k is a difftime object,

k + k + 1 would be read as k + (k + 1)

The code above would read it as (k + k) + 1

from lubridate.

garrettgman avatar garrettgman commented on August 21, 2024

To self: tomorrow update the subtraction code in a similar way

from lubridate.

hadley avatar hadley commented on August 21, 2024

It's a little weird that the precedence is different, but I don't think there's anything we can do about it.

from lubridate.

garrettgman avatar garrettgman commented on August 21, 2024

I've rewrote the subtraction code as well. The same precedence difference exists, but our addition and subtraction is consistent (and traditional) in this matter.

from lubridate.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.