Ensure data.frame/list elements are of a specific type and cast them if not
schema_cast.Rd
If any of the data-masked named expressions in ...
are not of the same type,
then the object attempts to be cast to the type specified in the expression.
.names
and .size
arguments can be used to check for given names and size
of the data.frame/list. The checking of type and the type conversion are from the
vctrs package (using vctrs::vec_is
and vctrs::vec_cast) and thus stick to the vctrs type conversion rules.
The checking of size is also from vctrs
(using vctrs::vec_size) and thus applies vctrs size rules.
Usage
schema_cast(.data, ...)
# S3 method for class 'data.frame'
schema_cast(
.data,
...,
.lossy = FALSE,
.names = NULL,
.size = NULL,
.class = NULL,
.error_call = caller_env()
)
# S3 method for class 'list'
schema_cast(
.data,
...,
.lossy = FALSE,
.names = NULL,
.size = NULL,
.class = NULL,
.error_call = caller_env()
)
Arguments
- .data
a data.frame or list to check the types schema of.
- ...
any number of
data-masking
name-value pairs to be evaluated using.data
as a data-mask. Should follow the format ofname = expected_type()
, e.g,var_x = integer()
orvar_x = var_y
.- .lossy
logical, if
TRUE
allow lossy casts.- .names
optional character vector of names which must be present in the data.frame/list.
- .size
optional scalar integerish value for the size that the data.frame/list must have.
- .class
class to assign to the error (passed to rlang::abort).
- .error_call
the call environment to use for the error (passed to rlang::abort).
Details
See also schema and schema_recycle, as well as cast_if_not for a non-data-masked version of casting.
Examples
# NB: Some of these examples are expected to produce an error. To
# prevent them from terminating a run with example() they are
# piped into a call to try().
li <- list(x = 1.1, y = "hi", z = 1L:2L)
# input remains the same if types match
li |>
schema_cast(x = double(), y = character(), z = integer()) |>
lapply(class)
#> $x
#> [1] "numeric"
#>
#> $y
#> [1] "character"
#>
#> $z
#> [1] "integer"
#>
li |>
schema_cast(y = numeric()) |>
try()
#> Error in eval(expr, envir) : Error in `schema_cast()`
#> ℹ Can't convert `y` <character> to <double>.
# => Error: Can't convert `y` <character> to <double>.
li |>
schema_cast(x = z) |>
try()
#> Error in eval(expr, envir) : Error in `schema_cast()`
#> ℹ Can't convert from `x` <double> to <integer> due to loss of precision. •
#> Locations: 1
# => Error: Can't convert from `x` <double> to <integer> due to loss of precision.
# with lossy casting
li |>
schema_cast(x = z, .lossy = TRUE) |>
lapply(class)
#> $x
#> [1] "integer"
#>
#> $y
#> [1] "character"
#>
#> $z
#> [1] "integer"
#>
# schema_cast works sequentially with quosures, so references to objects will be
# after they have been evaluated:
li$a <- 1L
li |>
schema_cast(z = x, a = z) |>
lapply(class)
#> $x
#> [1] "numeric"
#>
#> $y
#> [1] "character"
#>
#> $z
#> [1] "numeric"
#>
#> $a
#> [1] "numeric"
#>
li |>
schema_cast(x = numeric(), .size = 5) |>
try()
#> Error in eval(expr, envir) : Error in `schema_cast()`
#> ℹ Object `li` must have vctrs size `5`, not `4`.
# => Error: Object `li` must have vctrs size `5`, not `4`.
li |>
schema_cast(x = numeric(), .names = c("x", "p")) |>
try()
#> Error in eval(expr, envir) : Error in `schema_cast()`
#> ℹ Objects `p` not found in `li`.
# => Error: Names `p` not found in `li`.
# injection and glue can be used to supply expressions, names, and messages:
li <- list(x = 1L, z = 5.5)
x_name <- "x"
schema_cast(li, !!x_name := z) |>
lapply(class)
#> $x
#> [1] "numeric"
#>
#> $z
#> [1] "numeric"
#>
xg_name <- "{x_name}"
schema_cast(li, {{ xg_name }} := character()) |> try()
#> Error in eval(expr, envir) : Error in `schema_cast()`
#> ℹ Can't convert `x` <integer> to <character>.
# => Error: Can't convert `x` <integer> to <character>.