Skip to Content

dput() reveal the secret behind S3 class

# install needed R packages
remotes::update_packages(c('magrittr', 'tibble'), upgrade = TRUE)

The rotation project in Zhang Lab gives me reason and time to master Rcpp

1 Beginning


After learning the basics of Rcpp, I can’t wait to chieve something. When a C++ function needs to return a data.frame, I decide that rather than DataFrame, I want to return a tibble.

2 Development

I think it’s a small dish, since “Advanced R” already teaches me how to add attributes.

tibble::tibble(x = 1:2) %>% attributes()
## $names
## [1] "x"
## $row.names
## [1] 1 2
## $class
## [1] "tbl_df"     "tbl"        "data.frame"

I assume the following code is enough:

auto x = IntegerVector::create(1, 2);
auto df = List::create(Named("x") = x;

df.attr("class") = CharacterVector::create("tbl_df", "tbl", "data.frame");
df.attr("row.names") = IntegerVector::create(1, 2);

But actually it’s NOT (note the *)

# A tibble: 2 x 2
  a         b
* <chr> <int>
1 23        1
2 hao       2

Then I tried to not set df.attr("row.names"), and get a 0 row tibble.

Finally I give up and use a R function wrapper to convert data.frame to tibble.

3 Climax

Some days later, I find the secret

tibble::tibble(x = 1:2) %>% dput()
## structure(list(x = 1:2), row.names = c(NA, -2L), class = c("tbl_df", 
## "tbl", "data.frame"))

My God, df.attr("row.names") should be IntegerVector::create(NA_INTEGER, -2), whoever can know that?

4 Afterword

The point of this story is no matter how complicated an object is, you can always inspect the secret by dput() .