vctrs
vctrs copied to clipboard
Implement make_restore()?
Should we make it easier to implement functions that call another function and then vec_restore()
on the result?
x <- pillar::num(c(1, 2, 4), notation = "eng")
x
#> <pillar_num(eng)[3]>
#> [1] 1e0 2e0 4e0
# mean() keeps formatting
mean(x)
#> <pillar_num(eng)[1]>
#> [1] 2.33e0
# var() loses formatting
var(x)
#> [1] 2.333333
# Manual wrapper
var_ <- function(x, ...) {
out <- var(x, ...)
vctrs::vec_restore(out, x)
}
var_(x)
#> <pillar_num(eng)[1]>
#> [1] 2.33e0
# Easily create restoring wrappers?
make_restore <- function(fun) {
force(fun)
function(x, ...) {
out <- fun(x, ...)
vctrs::vec_restore(out, x)
}
}
var_ <- make_restore(var)
sd_ <- make_restore(sd)
var_(x)
#> <pillar_num(eng)[1]>
#> [1] 2.33e0
sd_(x)
#> <pillar_num(eng)[1]>
#> [1] 1.53e0
Created on 2021-04-12 by the reprex package (v1.0.0)
Note that it is undefined behaviour to call vec_restore()
on something other than the result of vec_proxy()
.
The suggested operator would allow things like taking the var()
of factors.
Added vec_proxy()
in https://github.com/r-lib/pillar/pull/316.
I'm seeing this for factors, var()
already checks this:
# Easily create restoring wrappers?
make_restore <- function(fun) {
force(fun)
function(x, ...) {
out <- fun(x, ...)
vctrs::vec_restore(out, vctrs::vec_proxy(x))
}
}
var_ <- make_restore(var)
sd_ <- make_restore(sd)
var_(factor(1:3))
#> Error in fun(x, ...): Calling var(x) on a factor x is defunct.
#> Use something like 'all(duplicated(x)[-1L])' to test for a constant vector.
Created on 2021-04-18 by the reprex package (v1.0.0)
ah yes that works out in this particular case because the proxy function of a factor is identity()
and var()
special-cases factors.
This:
make_restore <- function(fun) {
force(fun)
function(x, ...) {
out <- fun(x, ...)
vctrs::vec_restore(out, vctrs::vec_proxy(x))
}
}
Should be:
make_restore <- function(fun) {
force(fun)
function(x, ...) {
out <- fun(vctrs::vec_proxy(x), ...)
vctrs::vec_restore(out, x)
}
}
Proxy and restore are mostly internal functions at the moment.