2016-10-18 25 views
6

Mam kilka klas niestandardowych, na przykład:R - „nie wyświetlać na liście” metody liście niestandardowych klas

setClass("foo", slots = c(mat = "matrix")) 

chcę obsłużyć jak lista foo obiektów są „niepubliczne”.

mat <- matrix(rnorm(16), 4) 
foo <- new("foo", mat = mat) 
unlist(list(foo)) 

Myślałem, że może tworzyć metody c (co moim zdaniem było używane, ale być może niesłusznie) i unlist rozwiązałoby problem.

S3 wersja

#' @export 
unlist <- function(x, ...) UseMethod("unlist", x) 

#' @export 
unlist.default <- base::unlist 
#' @method unlist foo 
#' @export 
unlist.foo <- function(x, ...){ 
    print("called foo unlist") 
} 

S4 wersja

#' @export 
setMethod("unlist", 
      signature = "foo", 
      function(x, recursive = TRUE, use.names = TRUE){ 
      print("call foo unlist") 
      }) 

c funkcja

#' @export 
setMethod("c", 
      signature = "foo", 
      function(x, ..., recursive = FALSE){ 
      print("called foo c") 
}) 

Ale widzę tylko komunikat potwierdzenia podczas korzystania c bezpośrednio:

c(foo) 
[1] "called foo c" 

unlist prostu wraca do tego samego obiektu bez wiadomości druku

unlist(list(foo)) 
[[1]] 
An object of class "foo" 
Slot "mat": 
      [,1]  [,2]  [,3]  [,4] 
[1,] 0.6711541 -0.2783441 -0.4707375 -0.23060105 
[2,] 0.7408401 0.4076826 2.2757187 -0.48547413 
[3,] 1.8640581 0.3610619 -0.4632473 -0.06498348 
[4,] -0.5595930 0.6679157 -0.8142456 0.27499963 

Jeśli zadzwonię unlist(foo) potem dostaję komunikat druku ale muszę stosować go na liście foo obiektów. Wszelkie przemyślenia na temat tego, w jaki sposób mogę mieć listę nieopublikowaną, zajmują się niestandardowymi klasami na liście?

Docelowo chcę następuje powrót TRUE:

all.equal(unlist(list(foo)), unlist(list(mat))) 
+1

'unlist' nie wygląda jak metoda S3. Jeśli chcesz użyć swojej funkcji, musisz bezpośrednio wywołać 'unlist.foo' – Chrisss

+0

@Chrisss Chociaż użyłem' roxygen2' do wyeksportowania go jako S3, mam teraz jawnie utworzony 'unlist' jako S3. Nadal powoduje to ten sam problem. – cdeterman

+0

'unlist.foo' byłoby metodą dla S3, która dotyczyłaby obiektu takiego jak 'foo <- structure (matrix (rnorm (16), 4), class =" foo ")' ale twoja klasa wygląda jak S4 jeśli jestem nie mylić. – baptiste

Odpowiedz

0

boję się to nie jest możliwe. unlist określa typ jego danych wyjściowych na podstawie typów poszczególnych elementów listy, które pobiera. Jeśli wszystkie elementy są atomowe, tak jak w przypadku, gdy jedynym elementem jest foo (macierz), robi to coś z jego argumentem - argumenty wymusza na zwykłym wektorze atomowym (jest tylko jeden) i zapomina większość jego atrybutów (np. Wymiary). Jednak nie traktuje obiektów S4 (takich jak foo), które są oparte na wektorach atomowych, jako wektorach atomowych: te obiekty S4 pozostaną nietknięte w wyniku, a wynikiem będzie lista typów. Dlatego wywołanie unlist na list(foo) zwraca list(foo). Zachowanie jest zaimplementowane w C (do_unlist w bind.c) i wydaje mi się, że jest zgodne z dokumentacją.

do mimick pożądane zachowanie w podzestawie możliwych zastosowań z unlist, można prawdopodobnie realizować nową klasę dla listy foo obiektów określić list do foo, a następnie określić nowy unlist tym lista--foo klasa zachowywać się podobnie jak domyślna implementacja C unlist zachowuje się na liście wektorów atomowych (nie próbowałem).

Powiązane problemy