Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
billdenney opened this issue Mar 9, 2022 · 2 comments
Closed

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

billdenney opened this issue Mar 9, 2022 · 2 comments

Comments

@billdenney
Copy link
Contributor

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)

@billdenney
Copy link
Contributor Author

By the way, I'm happy to convert the code above into a PR, but I'm not sure when the number of columns would be >1. I think never, but it's not clear to me.

@Enchufa2
Copy link
Member

Enchufa2 commented Mar 10, 2022

Let me see. Maybe it's enough to redirect the call to as.data.frame.AsIs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants