tbl_df is transformed as list in S4 class

你说的曾经没有我的故事 提交于 2019-12-06 06:33:46

问题


When I tried to use tbl_df in S4 classes, tbl_df slots seems to be transformed into list.

library('tibble')
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 = 'firsttest')
tmp1@.Data
[[1]]
[1] 1 2 3 4 5

[[2]]
[1] 1 1 1 1 1

[[3]]
[1]  2  5 10 17 26

Can I visit the tmp1@.Data just like a tbl_df object? like

tmp1@.Data
# 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

回答1:


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



回答2:


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



来源:https://stackoverflow.com/questions/51825456/tbl-df-is-transformed-as-list-in-s4-class

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