2017-10-14 45 views
1

我迷迷糊糊關於integer向更高類型numeric傳播的問題,早在我自己的在它的上面級myclass結合:自己的類構建正確

x <- c(1L, 2L, 3L) 
class(x) # integer 

y <- x 
class(y) <- c("myclass", class(y)) 
class(y) # c("myclass", "integer") 

x2 <- x/10 
class(x2) # numeric - propagated to higher class numeric 

y2 <- y/10 
class(y2) # c("myclass", "integer") - not propagated to c("myclass", "numeric") 
y2 # 0.1 0.2 0.3 - but decimal numbers! 

y3 <- y2 
class(y3) <- setdiff(class(y3), "myclass") 
class(y3) # integer 
y3 # 0 0 0 - integers 

我正在尋找一種方式來要麼得到向上傳播到c("myclass", "numeric")如果操作不產生這樣的結果,或者換一種方式,以保持在擺脫了「MyClass的」部分(或兩者)的小數。我不想爲"myclass"定義我自己的操作,而是依賴派遣到基本類。

我知道我可以使用typeof()和內部存儲器之間進行區分,然後取出"myclass"by class<-和設置類"numeric"之前檢查它(或使用attr(obj, "class") <- NULL有作爲確定類,那麼它爲我做的)。但是,當我執行雙打操作時,如何獲得c("myclass", "numeric")

+1

只需將類設置爲'myclass':'class(x)< - 「myclass」'。您不需要爲存儲類型設置類;讓R處理它吧。 – nicola

+0

謝謝您的建議。我真的想保留原來的課程。 'myclass'應作爲各類課程的延伸,例如數字,邏輯,因素。 – Helix123

+0

請注意'數字','邏輯','整數','字符'和'列表'不像其他類一樣。他們沒有'class'屬性;而是他們的存儲類型決定了這個類。你總是可以通過通常的'.xxx'函數來確定一個對象是什麼,所以你基本上不需要有一個地方說明對象是什麼。 – nicola

回答

0

我通過使用groupGenerics爲類"myclass"解決了這個問題:不需要爲「myclass」的每個單一操作(+, - ,/,log,...)定義自己的操作,但可以依賴組(Ops,Math,Complex,Summary),請參閱?groupGeneric

這裏我通過一個例子展示瞭如何使用groupOps,Math和Complex組(類似於組摘要,但我並不需要它)。這個例子只是取消了圍繞基本類的類「myclass」,並且一旦在類"myclass"的對象上調用了來自三個組中的一個的操作,就再次重新添加它。當然,人們可以在定義的泛型中輕鬆地做更多的事情,但這只是爲了說明。 get(.Generic)(x)這裏是一個關鍵點:它爲基本類調用的操作獲取泛型並將其應用於對象x

Math.myclass <- function(x, ...) { 
# print("Math.myclass executed!") # debug output 

    if (inherits(x, "myclass")) class(x) <- setdiff(class(x), "myclass") 

    x <- get(.Generic)(x, ...) 
    ## do more stuff here ## 
    class(x) <- union("myclass", class(x)) 
    return(x) 
} 

Complex.myclass <- function(z) { 
# print("Complex.myclass executed!") # debug output 

    if (inherits(z, "myclass")) class(z) <- setdiff(class(z), "myclass") 

    z <- get(.Generic)(z) 
    ## do more stuff here ## 
    class(z) <- union("myclass", class(z)) 
    return(z) 
} 

Ops.myclass <- function(e1, e2) { 
# Ops can have 1 or 2 arguments 
# print("Ops.myclass executed!") # debug output 

    miss_e2 <- missing(e2) 

    # either one or both could be class "myclass" 
    if (inherits(e1, "myclass")) class(e1) <- setdiff(class(e1), "myclass") 
    if (!miss_e2 && inherits(e2, "myclass")) class(e2) <- setdiff(class(e2), "myclass") 

    res <- if (!miss_e2) { 
      get(.Generic)(e1, e2) 
      } else { 
      get(.Generic)(e1) 
      } 
    ## do more stuff here ## 
    class(res) <- union("myclass", class(res)) 
    return(res) 
} 
+0

這篇文章有助於找到答案:https ://stackoverflow.com/a/35903266/4640346 – Helix123