vctrs icon indicating copy to clipboard operation
vctrs copied to clipboard

`View()` fails with data frame with vctrs_rcrd column

Open jessesadler opened this issue 4 years ago • 3 comments

When trying to View() a data frame with a vctrs_rcrd-type column in RStudio the attempt fails with the error: "Error: Can't cast x <deb_lsd> to to ." It works with vctrs_vctr class.

I know that View() in Rstudio with vctrs_rcrd types is all funky, but it is difficult to not be able to view a whole data frame because it has one such column.

Example from rational class in S3 vignette:

library(vctrs)

new_rational <- function(n = integer(), d = integer()) {
  vec_assert(n, ptype = integer())
  vec_assert(d, ptype = integer())
  
  new_rcrd(list(n = n, d = d), class = "vctrs_rational")
}

rational <- function(n, d) {
  c(n, d) %<-% vec_cast_common(n, d, .to = integer())
  c(n, d) %<-% vec_recycle_common(n, d)
  
  new_rational(n, d)
}

format.vctrs_rational <- function(x, ...) {
  n <- field(x, "n")
  d <- field(x, "d")
  
  out <- paste0(n, "/", d)
  out[is.na(n) | is.na(d)] <- NA
  
  out
}

x <- data.frame(x = rational(1, 1:10))

# Error
View(x)

Implementing vec_cast.character.vctrs_rational by using format method solves the error.

# Cast coilerplate
vec_cast.vctrs_rational <- function(x, to, ...) UseMethod("vec_cast.vctrs_rational")
vec_cast.vctrs_rational.default <- function(x, to, ...) vec_default_cast(x, to)

# Cast to character
vec_cast.character.vctrs_rational <- function(x, to, ...) format(x, ...)

# Now View() works
View(x)

I do not really understand why View() works with a vctrs_vctr-type column, since casting to character() does not automatically work. If it makes sense to solve the issue by implementing a cast from vec_cast.character.vctrs_rational maybe just a mention of this in the S3 vignette would be useful.

jessesadler avatar Jul 18 '19 21:07 jessesadler

Is this something you'd be able to help with @romainfrancois?

lionel- avatar Sep 12 '22 15:09 lionel-

I think this is very related to https://github.com/rstudio/rstudio/issues/10073

Possibly it isn't working because the format() method is being registered in the global namespace? I think if you register it in a package then it works?

DavisVaughan avatar Sep 12 '22 17:09 DavisVaughan

Yea see this works in the latest RStudio daily build (and i think in the released build)

library(vctrs)
library(zeallot)

new_rational <- function(n = integer(), d = integer()) {
  vec_assert(n, ptype = integer())
  vec_assert(d, ptype = integer())
  
  new_rcrd(list(n = n, d = d), class = "vctrs_rational")
}

rational <- function(n, d) {
  c(n, d) %<-% vec_cast_common(n, d, .to = integer())
  c(n, d) %<-% vec_recycle_common(n, d)
  
  new_rational(n, d)
}

registerS3method("format", "vctrs_rational", function(x, ...) {
  n <- field(x, "n")
  d <- field(x, "d")
  
  out <- paste0(n, "/", d)
  out[is.na(n) | is.na(d)] <- NA
  
  out
})

x <- data.frame(x = rational(1, 1:10))

# Error
View(x)

So it has something to do with where format.vctrs_rational is getting registered

But in general the problem is fixed since this mostly occurs in packages

DavisVaughan avatar Sep 12 '22 17:09 DavisVaughan