Closed lrossouw closed 1 year ago
This issue https://github.com/tidyverse/lubridate/issues/919 describes the same problem but I think the fix did not address it.
Another example of the inconcistency:
library(lubridate)
#> Loading required package: timechange
#>
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#>
#> date, intersect, setdiff, union
# this is fine
stopifnot(period(months = c(1,2)) == months(c(1, 2)))
# but this fails
stopifnot(period(c(1, 2), units = c("months", "months")) == months(c(1, 2)))
#> Error: period(c(1, 2), units = c("months", "months")) == months(c(1, .... are not all TRUE
Another inconsistency when using a character vector below. You will see that using seperate num
/units
vectors results in a combined period.
library(tidyverse)
library(lubridate)
#> Loading required package: timechange
#>
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#>
#> date, intersect, setdiff, union
# data
data <- data.frame(
num = c(1,2,3),
units = c("weeks", "months", "days")
) %>%
mutate(period_text = paste(num, units))
# calc 2 ways
data<- data %>%
mutate(
period_1 = period(num, units),
period_2 = period(period_text)
)
data
#> num units period_text period_1 period_2
#> 1 1 weeks 1 weeks 2m 10d 0H 0M 0S 7d 0H 0M 0S
#> 2 2 months 2 months 2m 10d 0H 0M 0S 2m 0d 0H 0M 0S
#> 3 3 days 3 days 2m 10d 0H 0M 0S 3d 0H 0M 0S
stopifnot(data$period_1==data$period_2)
#> Error: data$period_1 == data$period_2 are not all TRUE
I was about to start coding a fix, but I see the above is essentially expected behaviour based on test cases. For example here it's clearly expected that period
combines the periods.
I would say there is some inconsistency with the way it handles the above where it's provided in another format. Should this behaviour not be controlled by some form of collapse
parameter similar to the way paste
works? And should this not be consistent across different ways in which period
can be used?
This is a very old interface to period and preserved for compatibility. In the beginning period
was able to produce only a singletone period. I am afraid we are stuck with it.
Thus you have two options:
> period(paste(c(1, 2), units = c("seconds", "months")))
[1] "1S" "2m 0d 0H 0M 0S"
> period(seconds = c(1, 0), months = c(0, 2))
[1] "1S" "2m 0d 0H 0M 0S"
Thanks I thought it might be like that after spotting the test cases. Weird inconsistent behaviour. I have gone for the paste version. Maybe a new period function to have consistent behaviour.
period
collapses vectorised input into a single period as opposed to producing the same length as vectors provided. It makes it not usable indplyr::mutate
for example.period
would be useful in this context if you have an input columns of units and want to produce an output column of those lengths (as opposed to collapsing) the period into a single period.