2016-02-26 63 views
0

尝试我在R中作为OO编程的第一次尝试,我宣布了一个S4对象TestObject,它有两个插槽,其中一个插槽(test.df)具有允许的data.frame类:tbl_df与S4对象槽

library("dplyr") 
library("methods") 

# Declare S4 Object 
setClass("TestObject", 
    slots = list(test.mat = "matrix", 
       test.df = "data.frame")) 

令我惊讶的是,当我尝试分配tbl_df的“类”的对象:

library("nycflights13") 
class(flights) 
## [1] "tbl_df"  "tbl"  "data.frame" 

它抛出一个错误:

test.object <- new("TestObject") 
slot(test.object, "test.mat") <- matrix(rnorm(10), 5, 2) 
slot(test.object, "test.df") <- flights 
## Error in checkSlotAssignment(object, name, value): c("assignment of an object of class \"tbl_df\" is not valid for slot 'test.df' in an object of class \"TestObject\"; is(value, \"data.frame\") is not TRUE", "assignment of an object of class \"tbl\" is not valid for slot 'test.df' in an object of class \"TestObject\"; is(value, \"data.frame\") is not TRUE", "assignment of an object of class \"data.frame\" is not valid for slot 'test.df' in an object of class \"TestObject\"; is(value, \"data.frame\") is not TRUE") 

我的印象是tbl_df只是围绕一个data.frame。我想也许我可以宣布tbl_df作为test.df允许类:

setClass("TestObject", 
    slots = list(test.mat = "matrix", 
       test.df = "tbl_df")) 
## Warning: undefined slot classes in definition of "TestObject": 
## test.df(class "tbl_df") 

但它似乎没有认识到它作为一个允许类。

看来,我将不得不在tbl_df转换成data.frame,为了使这项工作...

setClass("TestObject", 
    slots = list(test.mat = "matrix", 
       test.df = "data.frame")) 

slot(test.object, "test.df") <- as.data.frame(flights) 
## [1] "data.frame" 

但这样做就失去其作为一个tbl_df的好处(例如打印几行,所有列适合在一个屏幕上,等)

class(slot(test.object, "test.df")) 
head(slot(test.object, "test.df")) 
## year month day dep_time dep_delay arr_time arr_delay carrier tailnum 
## 1 2013  1 1  517   2  830  11  UA N14228 
## 2 2013  1 1  533   4  850  20  UA N24211 
## 3 2013  1 1  542   2  923  33  AA N619AA 
## 4 2013  1 1  544  -1  1004  -18  B6 N804JB 
## 5 2013  1 1  554  -6  812  -25  DL N668DN 
## 6 2013  1 1  554  -4  740  12  UA N39463 
## flight origin dest air_time distance hour minute 
## 1 1545 EWR IAH  227  1400 5  17 
## 2 1714 LGA IAH  227  1416 5  33 
## 3 1141 JFK MIA  160  1089 5  42 
## 4 725 JFK BQN  183  1576 5  44 
## 5 461 LGA ATL  116  762 5  54 
## 6 1696 EWR ORD  150  719 5  54 

我有一种感觉,我不理解怎么tbl_df(也许它不是一类)。但是,有没有办法让一个tbl_df“类”与S4和data.frame允许的类一起工作?

完整的代码可以在这里找到:

https://github.com/tinyheero/tbl-df-s4/blob/master/tbl-df-s4.Rmd

和相应的HTML:

https://htmlpreview.github.io/?https://github.com/tinyheero/tbl-df-s4/blob/master/tbl-df-s4.html

R对话详细

devtools::session_info() 
## Session info -------------------------------------------------------------- 
## setting value      
## version R version 3.2.2 (2015-08-14) 
## system x86_64, darwin14.5.0   
## ui  X11       
## language (EN)       
## collate en_CA.UTF-8     
## tz  America/Vancouver   
## date  2016-02-25 
## Packages ------------------------------------------------------------------ 
## package  * version date  source        
## assertthat  0.1  2013-12-06 CRAN (R 3.2.2)      
## DBI   0.3.1 2014-09-24 CRAN (R 3.2.2)      
## devtools  1.10.0 2016-01-23 CRAN (R 3.2.2)      
## digest   0.6.9 2016-01-08 CRAN (R 3.2.2)      
## dplyr  * 0.4.3 2015-09-01 CRAN (R 3.2.2)      
## evaluate  0.8  2015-09-18 CRAN (R 3.2.2)      
## formatR  1.2.1 2015-09-18 CRAN (R 3.2.2)      
## htmltools  0.3  2015-12-29 CRAN (R 3.2.2)      
## knitr  * 1.12.3 2016-01-22 CRAN (R 3.2.2)      
## magrittr  1.5  2014-11-22 CRAN (R 3.2.2)      
## memoise  0.2.1 2014-04-22 CRAN (R 3.2.2)      
## nycflights13 * 0.1  2014-07-22 CRAN (R 3.2.2)      
## R6    2.1.2 2016-01-26 CRAN (R 3.2.2)      
## Rcpp   0.12.3 2016-01-10 CRAN (R 3.2.2)      
## rmarkdown  0.9.5 2016-02-12 Github (rstudio/[email protected]) 
## stringi  1.0-1 2015-10-22 CRAN (R 3.2.2)      
## stringr  1.0.0 2015-04-30 CRAN (R 3.2.2)      
## yaml   2.1.13 2014-06-12 CRAN (R 3.2.2) 

许多在此先感谢。

回答

3

从S4S的角度来看,目前尚不清楚tbl_df真是data.frame。您可以使用setOldClass声明该关系,您必须提供tbl_df对象的类名称的完整列表。这样做对S4解释说'tbl_df'确实继承自data.frame

setOldClass(c("tbl_df", "tbl", "data.frame")) 
1

你可以尝试:

# allow S4 to see the class tbl_df 
setOldClass("tbl_df") 

# Declare S4 Object 
setClass(
    "TestObject", 
    representation(
     test.mat = "matrix", 
     test.df = "tbl_df" 
    ) 
)