2016-01-29 129 views
-1

在許多變種,類似的問題已經被問了很多次...... 但我不找到一個明確的建議:寫作「as.data.frame」自定義S3 Method對象

「出口S3方法作爲函數」

我寫了一個自定義的S3類roxygen2,稱之爲'my_item'。 這是構造函數:

my_item <- function(n) structure(list(n=n),class='my_item') 

我需要的是一種方法來定義一個"list of my_items => data.frame"投功能:

#' @method as.data.frame my_item 
#' @export 

as.data.frame.my_item <- function(x) ... 

只要我把它用這種方式my_item,它是好的:

as.data.frame(my_item('a')) 

但申請對象不能正常工作的列表同一呼叫,因爲class(list)是空的:

as.data.frame(list(my_item('a'),my_item('b'))) 

這也不能工作,因爲函數/方法不出口

as.data.frame.my_item(list(my_item('a'),my_item('b'))) 

這不明確的命名空間限定的工作:

my_pkg::as.data.frame.my_item(...) 

Error: 'as.data.frame.my_item' is not an exported object from 'namespace:my_pkg' 

在包動物園 ,這對於plot通用功能是可能的。

plot.zoo,一個S3方法,導出爲函數

動物園:: NAMESPACE

export(
    ... 
    "plot.zoo" 
    ... 
) 
S3method("plot", "zoo") 
S3method("as.data.frame", "zoo") 

所得包作用域是:

library(zoo) 

methods('as.data.frame') 

[1] as.data.frame.aovproj*  as.data.frame.array   as.data.frame.AsIs   
[4] as.data.frame.character  as.data.frame.chron*   as.data.frame.complex   
[7] as.data.frame.data.frame  as.data.frame.data.table*  as.data.frame.Date   
[10] as.data.frame.dates*   as.data.frame.default   as.data.frame.difftime  
[13] as.data.frame.factor   as.data.frame.ftable*   as.data.frame.integer   
[16] as.data.frame.ITime*   as.data.frame.list   as.data.frame.logical   
[19] as.data.frame.logLik*   as.data.frame.matrix   as.data.frame.model.matrix 
[22] as.data.frame.noquote   as.data.frame.numeric   as.data.frame.numeric_version 
[25] as.data.frame.ordered   as.data.frame.POSIXct   as.data.frame.POSIXlt   
[28] as.data.frame.raw    as.data.frame.shingle*  as.data.frame.table   
[31] as.data.frame.times*   as.data.frame.ts    as.data.frame.vector   
[34] as.data.frame.yearmon*  as.data.frame.yearqtr*  as.data.frame.zoo*   
see '?methods' for accessing help and source code 

methods('plot') 

[1] plot.acf*   plot.data.frame* plot.decomposed.ts* plot.default  plot.dendrogram* 
[6] plot.density*  plot.ecdf   plot.factor*  plot.formula*  plot.function  
[11] plot.hclust*  plot.histogram*  plot.HoltWinters* plot.isoreg*  plot.lm*   
[16] plot.medpolish*  plot.mlm*   plot.ppr*   plot.prcomp*  plot.princomp*  
[21] plot.profile.nls* plot.raster*  plot.shingle*  plot.spec*   plot.stepfun  
[26] plot.stl*   plot.table*   plot.times*   plot.trellis*  plot.ts    
[31] plot.tskernel*  plot.TukeyHSD*  plot.zoo   
see '?methods' for accessing help and source code 

這顯示plot.zoo已導出,as.data.frame.zoo*是否t出口


所以可能是問題是錯的。

一個更好的將是:

「如何實現鑄協議( '作爲-...')使用名單-的基礎-S3對象列表「是什麼時候?

+3

你發佈後你看過嗎?請格式化您的代碼 – rawr

+0

當我發佈時,我正在關閉;) – hute37

+0

這可能有點特殊情況,因爲函數本身(即as.data.frame)有一段時間 - 與案例相反其中之一是導出一個Roxygen與S3方法混淆的函數。如果你爲一個沒有句點的函數(例如定義一個'plot'或'summary'方法)做這個工作,它是否工作? –

回答

0

我已經採取了不同的方法:

  • 通過as.my_item_list()功能
  • 定義as.data.frame.my_item_list方法對我「定製」名單
  • 工作增加 'my_item'+'_list'類泛型列表
  • 用泛型調用DF轉換:as.data.frame(as.my_item_list(some_list))

在以下示例中,我取代my_item類名具有較短ob


DEFINITION

# ---(the 'ob' S3 constructor)--------------------------------------------- 

ob <- function(a,b) structure(list(a=a,b=b), class='ob') 
is.ob <- function(x) inherits(x,'ob') 

#---(the 'ob_list' cast for lists)----------------------------------------- 

as.ob_list <- function(x, ...) UseMethod('as.ob_list') 
as.ob_list.list <- function(x, ...) { 
    stopifnot(all(sapply(x,is.ob))) 
    class(x) <- append(class(x),'ob_list',after=0) 
    x 
} 

#---(as.data.frame.* methods)---------------------------------------------- 

as.data.frame.ob <- function(x, ...) data.frame(t(as.matrix(unlist(x)))) 
as.data.frame.ob_list <- function(x, ...) do.call('rbind', lapply(x,as.data.frame)) 

TEST

o1 <- ob(1,10) 
o2 <- ob(2,20) 
o3 <- ob(3,30) 

ol <- list(o1,o2,o3) 

df <- as.data.frame(as.ob_list(ol)) 

print(df) 

    a b 
1 1 10 
2 2 20 
3 3 30 

看起來不錯!

+0

好,但斯洛夫。在CRAN中有更好的方法,比如['dplyr coertion'](https://github.com/hadley/dplyr/blob/master/vignettes/data_frames.Rmd),... – hute37

+0

上面的實現取自http:// stackoverflow的.com /問題/ 4227223/R-列表到數據幀 – hute37