Skip to content

Feature Request: as.data.frame method for mixed_units  #309

@billdenney

Description

@billdenney

When putting mixed_units into a data.frame, they become regular units, and they also get unusual column names based on the list method for as.data.frame. I think that the fix is to add an as.data.frame method for mixed_units similar to what follows:

x_regular <- units::set_units(1, "m")
x_mixed <- units::mixed_units(units::set_units(1, "m"))
# Normal units work when put into a data.frame
df_units <- data.frame(A=x_regular)
df_units
#>       A
#> 1 1 [m]
class(df_units$A)
#> [1] "units"

# mixed_units give unusual names for the data.frame and lose their "mixed_units"
# class, when put into a data.frame
df_mixed_units <- data.frame(A=x_mixed)
df_mixed_units
#>   structure.1..units...structure.list.numerator....m...denominator...character.0....class....symbolic_units....class....units..
#> 1                                                                                                                         1 [m]
class(df_mixed_units[[1]])
#> [1] "units"

# Manually adding the mixed units gets around some data.frame internals to work
# as expected
df_mixed_units_manual <- data.frame(B=1)[, -1, drop=FALSE]
df_mixed_units_manual$A <- x_mixed
df_mixed_units_manual
#>       A
#> 1 1 [m]
class(df_mixed_units_manual$A)
#> [1] "mixed_units" "list"

x_mixed_no_list <- x_mixed
class(x_mixed_no_list) <- "mixed_units"
df_mixed_units_manual_no_list <- data.frame(A=x_mixed_no_list)
#> Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors): cannot coerce class '"mixed_units"' to a data.frame
df_mixed_units_manual_no_list
#> Error in eval(expr, envir, enclos): object 'df_mixed_units_manual_no_list' not found
class(df_mixed_units_manual$A)
#> [1] "mixed_units" "list"

as.data.frame.mixed_units <- function(x, row.names = NULL, optional = FALSE, ...) {
  df = as.data.frame(unlist(unclass(x)), row.names, optional, ...)
  if (ncol(df) != 1) {
    stop("unexpected number of data.frame conversions for mixed_units")
  }
  df[[1]] <- x
  if (!optional && ncol(df) == 1) {
    colnames(df) <- deparse(substitute(x))
  }
  df
}
df_mixed_units_manual_method <- data.frame(A=x_mixed)
df_mixed_units_manual_method
#>       A
#> 1 1 [m]
class(df_mixed_units_manual_method$A)
#> [1] "mixed_units" "list"

Created on 2022-03-09 by the reprex package (v2.0.1)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions