2010-11-22 12 views
6

Piszę klasę S3 w R, która jest po prostu liczbą całkowitą z przypisanymi do niej atrybutami. Jeśli x1 i x2 są obiektami tej klasy (nazywają to "myclass"), to chciałbym, żeby c (x1, x2) zwróciło wektor obiektów z klasy Myclass z oryginalną definicją klasy i atrybutami nienaruszonymi. Jednak udokumentowane zachowanie c() polega na usunięciu atrybutów, więc wydaje mi się, że muszę napisać własną metodę c.myclass(). Moje pytanie brzmi: jak mogę to zrobić?Jak napisać funkcję c() dla niestandardowej klasy S3 w R

Przykładem problemu:

myclass <- function(x, n) structure(x, class="myclass", n=n) 
x1 <- myclass(1, 5) 
x2 <- myclass(2, 6) 
c(x1, x2) 
[1] 1 2 

Tu wynik jest po prostu wektorem pozycji klasy numerycznych, a oryginalny atrybut n znika.

Patrząc na kod dla różnych pakietów, czasami zobaczyć kod jak poniżej, w której musimy zachować atrybut klasy, ale nic innego:

c.myclass <- function(..., recursive = F) { 
    structure(c(unlist(lapply(list(...), unclass))), class="myclass") 
} 

Niestety ja również nie można uzyskać to do pracy. Wynikiem wywołania c.myclass (x1, x2) jest wektor, w którym sam wektor ma klasę "myclass", ale gdzie każdy element w wektorze ma klasę numeryczną; Naprawdę chcę, aby każdy element w wektorze miał klasę "myclass". W praktyce będę również musiał uaktualnić tę metodę, aby zachować również inne atrybuty (np. Atrybut "n" w myclass).

Odpowiedz

4

To działa, ale zakładam, że do wniosku, że każdy element wektora ma klasy numeryczny bo robisz coś takiego:

foo <- c(x1, x2) 
class(foo[1]) 
class(foo[2]) 

Jeśli to przypadek i chcesz elementy wyodrębnione zachować atrybut myclass , aby zachować atrybuty, musisz napisać metodę podzestawu "[.myclass".

+0

Dzięki Joshua, Twoja sugestia zadziałała. – Abiel

7

Oto przykład, który ma (chyba), co chcesz za pośrednictwem konkretnych metod c i [:

c.myclass <- function(..., recursive = FALSE) { 
    dots <- list(...) 
    ns <- sapply(dots, attr, which = "n") 
    classes <- rep("myclass", length(dots)) 
    res <- structure(unlist(dots, recursive = FALSE), class = classes) 
    attr(res, "n") <- ns 
    res 
} 

`[.myclass` <- function (x, i) { 
    y <- unclass(x)[i] 
    ns <- attr(x, "n")[i] 
    class(y) <- "myclass" 
    attr(y, "n") <- ns 
    y 
} 


myclass <- function(x, n) structure(x, class = "myclass", n = n) 
x1 <- myclass(1, 5) 
x2 <- myclass(2, 6) 
c(x1, x2) 
c(x1, x2)[2] 

Ale to fuszerka na tym, że mamy do zarządzania obsługi ustawienie i podrzędnego dodatkowych atrybuty do przechowywania n. To jest naprawdę tylko wektor liczbowy z atrybutem do nagrywania n.

To może być bardziej naturalne pracować z ogólnymi wszystkimi wektorami, listą. Bit, który jest bardziej zaangażowany i może powyższe jest wystarczające w twoim przypadku?

Powiązane problemy