tbl_df is transformed as list in S4 class

家住魔仙堡 提交于 2019-12-04 14:14:33

S3 objects, just for simplification, are lists with an special attribute "class" which is used to call the correct generic function. print is a generic function that is being called when R outputs the tibble object.

library(tibble)
tb <- tibble(x = 1:5, y = 1, z = x ^ 2 + y)

dput(tb)
#structure(list(x = 1:5, y = c(1, 1, 1, 1, 1), z = c(2, 5, 10, 
#17, 26)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", 
#"data.frame"))

attributes(tb)
#$`names`
#[1] "x" "y" "z"
#
#$row.names
#[1] 1 2 3 4 5
#
#$class
#[1] "tbl_df"     "tbl"        "data.frame"

When you create an S4 class using an S3 parent class, R only store the list on the .Data slot. R still keeps the attributes of the S3 objects but not in the .Data slot. When you print the TestClass, you get the tibble output plus the S4 slots. If just want the S3 object you can use as(object,"S3").

setOldClass(c('tbl_df', 'tbl', 'data.frame'))
setClass(Class = 'TestClass', slots = c(name = 'character'), contains = 'tbl_df')
tmp1 <- new('TestClass', tibble(x = 1:5, y = 1, z = x ^ 2 + y), name = 'firsttest1')
tmp1
#Object of class "TestClass"
## A tibble: 5 x 3
#      x     y     z
#* <int> <dbl> <dbl>
#1     1     1     2
#2     2     1     5
#3     3     1    10
#4     4     1    17
#5     5     1    26
#Slot "name":
#[1] "firsttest1"

attributes(tmp1)
#$`names`
#[1] "x" "y" "z"
#
#$row.names
#[1] 1 2 3 4 5
#
#$.S3Class
#[1] "tbl_df"     "tbl"        "data.frame"
#
#$name
#[1] "firsttest1"
#
#$class
#[1] "TestClass"
#attr(,"package")
#[1] ".GlobalEnv"

as(tmp1,"S3")
## A tibble: 5 x 3
#      x     y     z
#* <int> <dbl> <dbl>
#1     1     1     2
#2     2     1     5
#3     3     1    10
#4     4     1    17
#5     5     1    26

Use contains = class(tibble()) in setClass(). More details see https://github.com/tidyverse/tibble/issues/618

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!