Re: [Rd] round.Date and trunc.Date not working / implemented
> Jiří Moravec > on Wed, 7 Feb 2024 10:23:15 +1300 writes: > This is my first time working with dates, so if the answer is "Duh, work > with POSIXt", please ignore it. > Why is not `round.Date` and `trunc.Date` "implemented" for `Date`? > Is this because `Date` is (mostly) a virtual class setup for a better > inheritance or is that something that is just missing? (like > `sort.data.frame`). Would R core welcome a patch? > I decided to convert some dates to date using `as.Date` function, which > converts to a plain `Date` class, because that felt natural. > But then when trying to round to closest year, I have realized that the > `round` and `trunc` for `Date` do not behave as for `POSIXt`. > I would assume that these will have equivalent output: > Sys.time() |> round("years") # 2024-01-01 NZDT > Sys.Date() |> round("years") # Error in round.default(...): non-numeric > argument to mathematical function > Looking at the code (and reading the documentation more carefully) shows > the issue, but this looks like an omission that should be patched. > -- Jirka You are wrong: They *are* implemented, both even visible since they are in the 'base' package! ==> they have help pages you can read Here are examples: > trunc(Sys.Date()) [1] "2024-02-08" > trunc(Sys.Date(), "month") [1] "2024-02-01" > trunc(Sys.Date(), "year") [1] "2024-01-01" > __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] round.Date and trunc.Date not working / implemented
> On 8 Feb 2024, at 15:15, Martin Maechler wrote: > >> Jiří Moravec >>on Wed, 7 Feb 2024 10:23:15 +1300 writes: > >> This is my first time working with dates, so if the answer is "Duh, work >> with POSIXt", please ignore it. > >> Why is not `round.Date` and `trunc.Date` "implemented" for `Date`? > >> Is this because `Date` is (mostly) a virtual class setup for a better >> inheritance or is that something that is just missing? (like >> `sort.data.frame`). Would R core welcome a patch? > >> I decided to convert some dates to date using `as.Date` function, which >> converts to a plain `Date` class, because that felt natural. > >> But then when trying to round to closest year, I have realized that the >> `round` and `trunc` for `Date` do not behave as for `POSIXt`. > >> I would assume that these will have equivalent output: > >> Sys.time() |> round("years") # 2024-01-01 NZDT > >> Sys.Date() |> round("years") # Error in round.default(...): non-numeric >> argument to mathematical function > > >> Looking at the code (and reading the documentation more carefully) shows >> the issue, but this looks like an omission that should be patched. > >> -- Jirka > > You are wrong: They *are* implemented, > both even visible since they are in the 'base' package! > > ==> they have help pages you can read > > Here are examples: > >> trunc(Sys.Date()) > [1] "2024-02-08" >> trunc(Sys.Date(), "month") > [1] "2024-02-01" >> trunc(Sys.Date(), "year") > [1] "2024-01-01" >> > Maybe he meant r$> Sys.time() |> round.POSIXt("years") [1] "2024-01-01 CET" r$> Sys.Date() |> round.POSIXt("years") [1] "2024-01-01 UTC" The only difference is the timezone > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] round.Date and trunc.Date not working / implemented
I just wanted to add some additional problems from trying to replicate this. `trunc` does indeed work as advertised here, as does calling `round.POSIXt(Sys.Date())` and `round(Sys.Date())`. These functions are definitely implemented. However, I am also able to replicate Jiří’s error: ``` > round(Sys.Date()) [1] "2024-02-08" > round(Sys.time(), 'years') [1] "2024-01-01 EST" > round(Sys.Date(), 'years') Error in round.default(19761, "years") : non-numeric argument to mathematical function ``` Specifying `units="years"` causes errors — either an error from named argument (`unused argument units="years"`) or the above error when the argument is unnamed. The error they’re experiencing isn’t actually from `round.Date`, it’s from trying to call `round("years")`, which is done implicitly when `"years"` is provided as an unnamed second argument to `round()`. I suspect that the original bug report is referencing this behavior. Yes, it is correct that `round.Date` does not accept a `units` parameter as implemented and as specified in the help file. However, it does feel a little odd that `round.POSIXt` does accept a `units` parameter, but `round.Date` does not. Adding that capability would be fairly simple, unless there are other reasons why it isn’t implemented. Just my quick thoughts. -Aidan --- Aidan Lakshman (he/him) http://www.ahl27.com/ On 8 Feb 2024, at 9:36, Olivier Benz via R-devel wrote: >> On 8 Feb 2024, at 15:15, Martin Maechler wrote: >> >>> Jiří Moravec >>>on Wed, 7 Feb 2024 10:23:15 +1300 writes: >> >>> This is my first time working with dates, so if the answer is "Duh, work >>> with POSIXt", please ignore it. >> >>> Why is not `round.Date` and `trunc.Date` "implemented" for `Date`? >> >>> Is this because `Date` is (mostly) a virtual class setup for a better >>> inheritance or is that something that is just missing? (like >>> `sort.data.frame`). Would R core welcome a patch? >> >>> I decided to convert some dates to date using `as.Date` function, which >>> converts to a plain `Date` class, because that felt natural. >> >>> But then when trying to round to closest year, I have realized that the >>> `round` and `trunc` for `Date` do not behave as for `POSIXt`. >> >>> I would assume that these will have equivalent output: >> >>> Sys.time() |> round("years") # 2024-01-01 NZDT >> >>> Sys.Date() |> round("years") # Error in round.default(...): non-numeric >>> argument to mathematical function >> >> >>> Looking at the code (and reading the documentation more carefully) shows >>> the issue, but this looks like an omission that should be patched. >> >>> -- Jirka >> >> You are wrong: They *are* implemented, >> both even visible since they are in the 'base' package! >> >> ==> they have help pages you can read >> >> Here are examples: >> >>> trunc(Sys.Date()) >> [1] "2024-02-08" >>> trunc(Sys.Date(), "month") >> [1] "2024-02-01" >>> trunc(Sys.Date(), "year") >> [1] "2024-01-01" >>> >> > > Maybe he meant > > r$> Sys.time() |> round.POSIXt("years") > [1] "2024-01-01 CET" > > r$> Sys.Date() |> round.POSIXt("years") > [1] "2024-01-01 UTC" > > The only difference is the timezone > >> __ >> R-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] round.Date and trunc.Date not working / implemented
Às 14:36 de 08/02/2024, Olivier Benz via R-devel escreveu: On 8 Feb 2024, at 15:15, Martin Maechler wrote: Jiří Moravec on Wed, 7 Feb 2024 10:23:15 +1300 writes: This is my first time working with dates, so if the answer is "Duh, work with POSIXt", please ignore it. Why is not `round.Date` and `trunc.Date` "implemented" for `Date`? Is this because `Date` is (mostly) a virtual class setup for a better inheritance or is that something that is just missing? (like `sort.data.frame`). Would R core welcome a patch? I decided to convert some dates to date using `as.Date` function, which converts to a plain `Date` class, because that felt natural. But then when trying to round to closest year, I have realized that the `round` and `trunc` for `Date` do not behave as for `POSIXt`. I would assume that these will have equivalent output: Sys.time() |> round("years") # 2024-01-01 NZDT Sys.Date() |> round("years") # Error in round.default(...): non-numeric argument to mathematical function Looking at the code (and reading the documentation more carefully) shows the issue, but this looks like an omission that should be patched. -- Jirka You are wrong: They *are* implemented, both even visible since they are in the 'base' package! ==> they have help pages you can read Here are examples: trunc(Sys.Date()) [1] "2024-02-08" trunc(Sys.Date(), "month") [1] "2024-02-01" trunc(Sys.Date(), "year") [1] "2024-01-01" Maybe he meant r$> Sys.time() |> round.POSIXt("years") [1] "2024-01-01 CET" r$> Sys.Date() |> round.POSIXt("years") [1] "2024-01-01 UTC" The only difference is the timezone __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel Hello, You are right that the timezones are different but Sys.date() returns an object of class "Date" so the method called is not that one. Here an example with trunc. Sys.Date() |> class() Sys.Date() |> trunc("years") Sys.Date() |> trunc.Date("years") Sys.Date() |> trunc.POSIXt("years") As for the OP, the problem is thhat the generic roun())) doesn't have unit argument. So I am nnnot understanding why round.POSIXt works. Sys.Date() |> round("years") #> Error in round.default(structure(19761, class = "Date"), "years"): non-numeric argument to mathematical function Sys.Date() |> round.Date("years") #> Error in NextMethod(): generic function not specified Sys.Date() |> round.POSIXt("years") #> [1] "2024-01-01 UTC" Sys.Date() |> round.POSIXt("months") #> [1] "2024-02-01 UTC" Sys.Date() |> round.POSIXt("days") #> [1] "2024-02-08 UTC" Hope this helps, Rui Barradas -- Este e-mail foi analisado pelo software antivírus AVG para verificar a presença de vírus. www.avg.com __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] round.Date and trunc.Date not working / implemented
Technically, there is a round() for 'Date' objects, but it doesn't seem very useful, because it basically just fall back to the default round() method, which only takes the 'digits' argument. Here's an example: > date <- Sys.Date() > class(date) [1] "Date" We see that there are only two round() methods in addition to the implicit built-in one; > methods("round") [1] round.Date round.POSIXt see '?methods' for accessing help and source code Looking at round() for 'Date'; > round.Date function (x, ...) { .Date(NextMethod(), oldClass(x)) } we see that it defers to the next method here, which is the built-in one. The built-in one, only accepts 'digits', which does nothing for digits >= 0. For digits < 0, it rounds to power of ten, e.g. > date [1] "2024-02-08" > round(date, digits = 0) [1] "2024-02-08" > round(date, digits = 1) [1] "2024-02-08" > round(date, digits = 2) [1] "2024-02-08" > round(date, digits = -1) [1] "2024-02-07" > round(date, digits = -2) [1] "2024-03-18" > round(date, digits = -3) [1] "2024-10-04" > round(date, digits = -4) [1] "2024-10-04" > round(date, digits = -5) [1] "1970-01-01" So, although technically invalid, OPs remark is a valid one. I'd also expect `round()` for Date to support 'units' similar to timestamps, e.g. > time <- Sys.time() > class(time) [1] "POSIXct" "POSIXt" > time [1] "2024-02-08 09:17:02 PST" > round(time, units = "days") [1] "2024-02-08 PST" > round(time, units = "months") [1] "2024-02-01 PST" > round(time, units = "years") [1] "2024-01-01 PST" So, I agree with OP that one would expect: > round(date, units = "days") [1] "2024-02-08" > round(date, units = "months") [1] "2024-02-01" > round(date, units = "years") [1] "2024-01-01" to also work here. FWIW, I don't think we want to encourage circumventing the S3 generic and calling S3 methods directly, i.e. I don't recommend doing things like round.POSIXt(...). Ideally, all S3 methods in R would be non-exported, but some remain exported for legacy reason. But, I think we should treat them as if they in the future will become non-exported. /Henrik On Thu, Feb 8, 2024 at 8:18 AM Olivier Benz via R-devel wrote: > > > On 8 Feb 2024, at 15:15, Martin Maechler wrote: > > > >> Jiří Moravec > >>on Wed, 7 Feb 2024 10:23:15 +1300 writes: > > > >> This is my first time working with dates, so if the answer is "Duh, work > >> with POSIXt", please ignore it. > > > >> Why is not `round.Date` and `trunc.Date` "implemented" for `Date`? > > > >> Is this because `Date` is (mostly) a virtual class setup for a better > >> inheritance or is that something that is just missing? (like > >> `sort.data.frame`). Would R core welcome a patch? > > > >> I decided to convert some dates to date using `as.Date` function, which > >> converts to a plain `Date` class, because that felt natural. > > > >> But then when trying to round to closest year, I have realized that the > >> `round` and `trunc` for `Date` do not behave as for `POSIXt`. > > > >> I would assume that these will have equivalent output: > > > >> Sys.time() |> round("years") # 2024-01-01 NZDT > > > >> Sys.Date() |> round("years") # Error in round.default(...): non-numeric > >> argument to mathematical function > > > > > >> Looking at the code (and reading the documentation more carefully) shows > >> the issue, but this looks like an omission that should be patched. > > > >> -- Jirka > > > > You are wrong: They *are* implemented, > > both even visible since they are in the 'base' package! > > > > ==> they have help pages you can read > > > > Here are examples: > > > >> trunc(Sys.Date()) > > [1] "2024-02-08" > >> trunc(Sys.Date(), "month") > > [1] "2024-02-01" > >> trunc(Sys.Date(), "year") > > [1] "2024-01-01" > >> > > > > Maybe he meant > > r$> Sys.time() |> round.POSIXt("years") > [1] "2024-01-01 CET" > > r$> Sys.Date() |> round.POSIXt("years") > [1] "2024-01-01 UTC" > > The only difference is the timezone > > > __ > > R-devel@r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel On Thu, Feb 8, 2024 at 9:06 AM Rui Barradas wrote: > > Às 14:36 de 08/02/2024, Olivier Benz via R-devel escreveu: > >> On 8 Feb 2024, at 15:15, Martin Maechler > >> wrote: > >> > >>> Jiří Moravec > >>> on Wed, 7 Feb 2024 10:23:15 +1300 writes: > >> > >>> This is my first time working with dates, so if the answer is "Duh, work > >>> with POSIXt", please ignore it. > >> > >>> Why is not `round.Date` and `trunc.Date` "implemented" for `Date`? > >> > >>> Is this because `Date` is (mostly) a virtual class setup for a better > >>> inheritance or is that something that is just missing? (like > >>> `sort.data.frame`). Would R core welcome a patch? > >> > >>> I decided to convert some dates to date using `as.Date` function, which > >>> converts to a plain `Date` class,
Re: [Rd] round.Date and trunc.Date not working / implemented
This is a workaround, and could be the basis for a round.Date improvement: date <- Sys.Date() as.Date(round(as.POSIXct(date), "years")) as.Date(round(as.POSIXct(Sys.Date() + 180), "years")) Duncan Murdoch On 08/02/2024 12:23 p.m., Henrik Bengtsson wrote: Technically, there is a round() for 'Date' objects, but it doesn't seem very useful, because it basically just fall back to the default round() method, which only takes the 'digits' argument. Here's an example: date <- Sys.Date() class(date) [1] "Date" We see that there are only two round() methods in addition to the implicit built-in one; methods("round") [1] round.Date round.POSIXt see '?methods' for accessing help and source code Looking at round() for 'Date'; round.Date function (x, ...) { .Date(NextMethod(), oldClass(x)) } we see that it defers to the next method here, which is the built-in one. The built-in one, only accepts 'digits', which does nothing for digits >= 0. For digits < 0, it rounds to power of ten, e.g. date [1] "2024-02-08" round(date, digits = 0) [1] "2024-02-08" round(date, digits = 1) [1] "2024-02-08" round(date, digits = 2) [1] "2024-02-08" round(date, digits = -1) [1] "2024-02-07" round(date, digits = -2) [1] "2024-03-18" round(date, digits = -3) [1] "2024-10-04" round(date, digits = -4) [1] "2024-10-04" round(date, digits = -5) [1] "1970-01-01" So, although technically invalid, OPs remark is a valid one. I'd also expect `round()` for Date to support 'units' similar to timestamps, e.g. time <- Sys.time() class(time) [1] "POSIXct" "POSIXt" time [1] "2024-02-08 09:17:02 PST" round(time, units = "days") [1] "2024-02-08 PST" round(time, units = "months") [1] "2024-02-01 PST" round(time, units = "years") [1] "2024-01-01 PST" So, I agree with OP that one would expect: round(date, units = "days") [1] "2024-02-08" round(date, units = "months") [1] "2024-02-01" round(date, units = "years") [1] "2024-01-01" to also work here. FWIW, I don't think we want to encourage circumventing the S3 generic and calling S3 methods directly, i.e. I don't recommend doing things like round.POSIXt(...). Ideally, all S3 methods in R would be non-exported, but some remain exported for legacy reason. But, I think we should treat them as if they in the future will become non-exported. /Henrik On Thu, Feb 8, 2024 at 8:18 AM Olivier Benz via R-devel wrote: On 8 Feb 2024, at 15:15, Martin Maechler wrote: Jiří Moravec on Wed, 7 Feb 2024 10:23:15 +1300 writes: This is my first time working with dates, so if the answer is "Duh, work with POSIXt", please ignore it. Why is not `round.Date` and `trunc.Date` "implemented" for `Date`? Is this because `Date` is (mostly) a virtual class setup for a better inheritance or is that something that is just missing? (like `sort.data.frame`). Would R core welcome a patch? I decided to convert some dates to date using `as.Date` function, which converts to a plain `Date` class, because that felt natural. But then when trying to round to closest year, I have realized that the `round` and `trunc` for `Date` do not behave as for `POSIXt`. I would assume that these will have equivalent output: Sys.time() |> round("years") # 2024-01-01 NZDT Sys.Date() |> round("years") # Error in round.default(...): non-numeric argument to mathematical function Looking at the code (and reading the documentation more carefully) shows the issue, but this looks like an omission that should be patched. -- Jirka You are wrong: They *are* implemented, both even visible since they are in the 'base' package! ==> they have help pages you can read Here are examples: trunc(Sys.Date()) [1] "2024-02-08" trunc(Sys.Date(), "month") [1] "2024-02-01" trunc(Sys.Date(), "year") [1] "2024-01-01" Maybe he meant r$> Sys.time() |> round.POSIXt("years") [1] "2024-01-01 CET" r$> Sys.Date() |> round.POSIXt("years") [1] "2024-01-01 UTC" The only difference is the timezone __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel On Thu, Feb 8, 2024 at 9:06 AM Rui Barradas wrote: Às 14:36 de 08/02/2024, Olivier Benz via R-devel escreveu: On 8 Feb 2024, at 15:15, Martin Maechler wrote: Jiří Moravec on Wed, 7 Feb 2024 10:23:15 +1300 writes: This is my first time working with dates, so if the answer is "Duh, work with POSIXt", please ignore it. Why is not `round.Date` and `trunc.Date` "implemented" for `Date`? Is this because `Date` is (mostly) a virtual class setup for a better inheritance or is that something that is just missing? (like `sort.data.frame`). Would R core welcome a patch? I decided to convert some dates to date using `as.Date` function, which converts to a plain `Date` class, because that felt natural.