Comments (7)
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.
Try +.duration <- +.POSIXt <- .difftime
and then let me know what doesn't work.
from lubridate.
- 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)
- 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.
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.
To self: tomorrow update the subtraction code in a similar way
from lubridate.
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.
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)
- Problems with POSIXct in R 4.3.2 HOT 1
- 'OO' format option not recognized for parsing ISO 8601 time zone offsets
- `parse_date_time()` cannot match missing zeroes
- Inconsistent behavior of `parse_date_time()` inside `dplyr::mutate()` HOT 2
- month() and otehrs fail on objects from class 'timeDate'
- ymd_hms() function left-pads some dates that have missing "seconds" values
- round_date in 0.1 sec doesn't work correctly
- FR: int_overlaps with exclusive endpoints
- unique() always zero for periods HOT 1
- Implement Set Operations methods for Dates HOT 1
- Parsing dates with `my` seems to have a limit size
- Do we need something like `%m-%` to subtract years from leap 02/29? HOT 1
- Cannot compute `<date> + lubridate::year(1)` when `<date>` is a leap day. HOT 1
- m:s:ms time data
- `dmy()` not failing (and returning incorrect date) on wrong date format
- ceiling_date() issue when using multi units
- Fractional Seconds with conversion and rounding/truncation?
- mdy("04 July 2019") GIVES "2019-04-20" : Instead should give an error.
- data.table merge doesn't work with intervals HOT 1
- yearmonth() throws an error with C_force_tz
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lubridate.