Closed DavisVaughan closed 1 year ago
# but it isn't quite right either (should be an error)
update(as.Date(c("2019-01-01", "2019-01-02")), days = integer())
#> [1] "2019-01-01" "2019-01-02"
# (should be size 0 result b/c we take the common size)
update(as.Date(c("2019-01-01")), days = integer())
#> [1] "2019-01-01"
Why should first one be an error and the second one not?
The 2nd would be an error if we always recycled to the size of x
. i.e. we wouldn't be able to recycle the size of days
(0) to the size of x
(1).
But we don't, it seems like (for better or worse) update()
takes the common size, as seen by:
# proof that we are generally taking the common size:
update(as.Date(c("2019-01-01")), days = 1:3)
#> [1] "2019-01-01" "2019-01-02" "2019-01-03"
so it should obey common size rules, which means that something of size 1 can be recycled to the size of anything else.
So in this example, the size 1 x
gets recycled to the size 0 days
since the common size of 1 and 0 is 0.
# (should be size 0 result b/c we take the common size)
update(as.Date(c("2019-01-01")), days = integer())
#> [1] "2019-01-01"
vctrs examples:
library(vctrs)
# common size of 1 and 0 is 0 because 1 recycles to size of anything
vec_size_common("x", character())
#> [1] 0
# common size of 3 and 0 is 0 because 3 and 0 are incompatible
vec_size_common(c("x", "y", "z"), character())
#> Error:
#> ! Can't recycle `..1` (size 3) to match `..2` (size 0).
Fixed in devel. Though the error messages should be improved in the future.
> update(as.Date(c("2019-01-01", "2019-01-02")), days = 1:3)
Error in C_time_update(out, updates, tz, roll_month, roll_dst, week_start, (from cpp11.R#24) :
time_update: length of dt vector must be 1 or match the length of updating vectors
> update(as.Date(c("2019-01-01", "2019-01-02")), days = integer())
Error in C_time_update(out, updates, tz, roll_month, roll_dst, week_start, (from cpp11.R#24) :
time_update: Incompatible size of 'mday' vector
> update(as.Date(c("2019-01-01")), days = integer())
Error in C_time_update(out, updates, tz, roll_month, roll_dst, week_start, (from cpp11.R#24) :
time_update: Incompatible size of 'mday' vector
What does update(as.Date(c("2019-01-01")), days = 1:3)
give? If that works, then this should not have been an error:
> update(as.Date(c("2019-01-01")), days = integer())
Error in C_time_update(out, updates, tz, roll_month, roll_dst, week_start, (from cpp11.R#24) :
time_update: Incompatible size of 'mday' vector
update(as.Date(c("2019-01-01")), days = 1:3)
is not an error of course.
To my mind input vector and updates are not symmetric. To me a more natural approach is to not allow empty updates. Those are likely due to a logical error. An empty input date-time does make sense though.
I am not a stickler to this but replication to the parameter length feels surprising. For instance I would not want day(x) <- integer()
to obliterate x
. Or do I?
is there a technical issue created somehwere downstream if the replication to 0 parameter length
is not followed?
library(vctrs)
# common size of 1 and 0 is 0 because 1 recycles to size of anything
vec_size_common("x", character())
#> [1] 0
# common size of 3 and 0 is 0 because 3 and 0 are incompatible
vec_size_common(c("x", "y", "z"), character())
#> Error:
#> ! Can't recycle `..1` (size 3) to match `..2` (size 0).
Also the other way around update(empty(), "1 month")
would work but update(empty(), c("1m", "2m"))
would error. Right?
So unless there is a truly fundamental reason to to follow this rule I would rather keep it asymmetric.
Created on 2022-10-05 with reprex v2.0.2