diff --git a/NEWS.md b/NEWS.md index 62ff1afb7..c895e1fa2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,6 +10,9 @@ `Series`, `DataFrame`, and in the `$list` and `$arr` subnamespaces. For example, `pl$col("a", "b", "c")$to_struct()` should be replaced with `pl$struct(c("a", "b", "c"))` (#1092). +- `pl$Struct()` now only accepts named inputs and objects of class `RPolarsField`. + For example, `pl$Struct(pl$Boolean)` doesn't work anymore and should be named + like `pl$Struct(a = pl$Boolean)` (#1053). ## Polars R Package 0.16.4 diff --git a/R/datatype.R b/R/datatype.R index 4104ba3bc..3ba7951ae 100644 --- a/R/datatype.R +++ b/R/datatype.R @@ -212,15 +212,15 @@ DataType_Duration = function(time_unit = "us") { #' multiple ways to create columns of data type `Struct` in a `DataFrame` or #' a `Series`, see the examples. #' -#' @param ... RPolarsDataType objects -#' @return a list DataType with an inner DataType +#' @param ... Either named inputs of the form `field_name = datatype` or objects +#' of class `RPolarsField` created by [`pl$Field()`][pl_Field]. +#' @return A Struct DataType containing a list of Fields #' @examples #' # create a Struct-DataType -#' pl$Struct(pl$Boolean) -#' pl$Struct(foo = pl$Int32, bar = pl$Float64) +#' pl$Struct(foo = pl$Int32, pl$Field("bar", pl$Boolean)) #' #' # check if an element is any kind of Struct() -#' test = pl$Struct(pl$UInt64) +#' test = pl$Struct(a = pl$UInt64) #' pl$same_outer_dt(test, pl$Struct()) #' #' # `test` is a type of Struct, but it doesn't mean it is equal to an empty Struct @@ -252,34 +252,30 @@ DataType_Duration = function(time_unit = "us") { #' #' out$schema DataType_Struct = function(...) { + uw = \(res) unwrap(res, "in pl$Struct():") + err_message = Err_plain("`pl$Struct()` only accepts named inputs or input of class RPolarsField.") result({ largs = list2(...) if (length(largs) >= 1 && is.list(largs[[1]])) { largs = largs[[1]] - element_name = "list element" - } else { - element_name = "positional argument" } - mapply( - names(largs) %||% character(length(largs)), - largs, - seq_along(largs), - FUN = \(name, arg, i) { - if (inherits(arg, "RPolarsDataType")) { - return(pl$Field(name, arg)) - } - if (inherits(arg, "RPolarsRField")) { - return(arg) - } - stop(sprintf( - "%s [%s] {name:'%s', value:%s} must either be a Field (pl$Field) or a named DataType", - element_name, i, name, arg - )) - }, SIMPLIFY = FALSE - ) + lapply(seq_along(largs), function(x) { + name = names(largs)[x] + dtype = largs[[x]] + if (inherits(dtype, "RPolarsRField")) { + return(dtype) + } + if (is.null(name)) { + err_message |> uw() + } + if (inherits(dtype, "RPolarsDataType")) { + return(pl$Field(name, dtype)) + } + err_message |> uw() + }) }) |> and_then(DataType$new_struct) |> - unwrap("in pl$Struct:") + uw() } #' Create Array DataType diff --git a/man/DataType_Struct.Rd b/man/DataType_Struct.Rd index 3870652a5..a2f9041d4 100644 --- a/man/DataType_Struct.Rd +++ b/man/DataType_Struct.Rd @@ -7,10 +7,11 @@ DataType_Struct(...) } \arguments{ -\item{...}{RPolarsDataType objects} +\item{...}{Either named inputs of the form \code{field_name = datatype} or objects +of class \code{RPolarsField} created by \code{\link[=pl_Field]{pl$Field()}}.} } \value{ -a list DataType with an inner DataType +A Struct DataType containing a list of Fields } \description{ One can create a \code{Struct} data type with \code{pl$Struct()}. There are also @@ -19,11 +20,10 @@ a \code{Series}, see the examples. } \examples{ # create a Struct-DataType -pl$Struct(pl$Boolean) -pl$Struct(foo = pl$Int32, bar = pl$Float64) +pl$Struct(foo = pl$Int32, pl$Field("bar", pl$Boolean)) # check if an element is any kind of Struct() -test = pl$Struct(pl$UInt64) +test = pl$Struct(a = pl$UInt64) pl$same_outer_dt(test, pl$Struct()) # `test` is a type of Struct, but it doesn't mean it is equal to an empty Struct diff --git a/tests/testthat/test-datatype.R b/tests/testthat/test-datatype.R index d44bf7ca0..8979b559c 100644 --- a/tests/testthat/test-datatype.R +++ b/tests/testthat/test-datatype.R @@ -27,7 +27,7 @@ test_that("plStruct", { # wrong uses expect_grepl_error( pl$Struct(bin = pl$Binary, pl$Boolean, "abc"), - "must either be a Field" + "only accepts named inputs or input of class RPolarsField." ) })