2014-07-21 23 views
6

Wiąże się to z następujących pocztowych Problems passing arguments with callNextMethod() in RKorzystanie callNextMethod() w funkcji akcesor w R

piszę akcesorów dla dwóch klas, S4 'foo' i 'bar'. 'bar' dziedziczy z foo i jest rozszerzany tylko o kilka slotów. Zamiast pisać pełną funkcję accessor dla obiektów klasy 'bar', chcę przekazać argumenty do metody callNextMethod() podczas uzyskiwania dostępu do gniazda, które jest dziedziczone przez 'foo'. Mój kod wygląda następująco:

foo <- setClass("foo", representation(x = "numeric", y = "numeric")) 
bar <- setClass("bar", representation(distance = "numeric"), contains = "foo") 

setMethod("[", "bar", function(x, i, j, drop) { 
    if (i == "distance") { 
    return([email protected]) 
    } else { 
     callNextMethod() 
    } 
} 
) 

setMethod("[", "foo", function(x, i, j, drop) { 
    if (i == "x") { 
    return([email protected]) 
    } else { 
     if (i == "y") { 
     return([email protected]) 
     } 
    } 
} 
) 

Teraz spróbujmy:

f <- new("foo", x = 1, y = 2) 
b <- new("bar", x = 3, y = 4, distance = 5) 
f["x"] 
f["y"] 

akcesor dla obiektu 'f' klasy 'foo' właściwie powraca:

> f["x"] 
[1] 1 
> f["y"] 
[1] 2 

Gdy próbuję aby uzyskać dostęp do szczeliny "odległość" obiektu "b" klasy "bar", akcesor również prawidłowo zwraca:

> b["distance"] 
[1] 5 

Problem występuje, gdy próbuję uzyskać dostęp do dowolnego z gniazd obiektu "b" klasy "bar", które są dziedziczone po "foo". Gdy próbuję:

b["x"] 
b["y"] 

pojawia się następujący komunikat o błędzie:

Error in callNextMethod() : bad object found as method (class “function”) 

Czytałem zalecenia z tego postu Problems passing arguments with callNextMethod() in R ale nie mogę określić ogólny dla „[” i stara się przekazać argumenty jawnie na callNextMethod() również nie powiodło się.

Z pewnością robię coś nie tak! Przeczytałem kilka źródeł na temat dziedziczenia i nie mogę zidentyfikować problemu i mam nadzieję, że ludzie będą mogli mnie poprowadzić we właściwym kierunku.

Dzięki

Maks

+0

wiem „dlaczego” nie działa patrząc na kodzie źródłowym 'callNextMethod' ale nie mam każdy pomysł, dlaczego nie działa, biorąc pod uwagę to, co masz tutaj. Dobre pytanie! – stanekam

Odpowiedz

4

Twoje metody zarówno opuścić jeden z pięciu argumentów formalnych wymaganych przez jakikolwiek [ metody, a mianowicie wielokropka (...).

args(getGeneric("[")) 
# function (x, i, j, ..., drop = TRUE) 
# NULL 

włączenie go jako formalny w obu definicjach metoda rozwiązuje problem:

setMethod("[", "bar", function(x, i, j, ..., drop) { 
    if (i == "distance") { 
    return([email protected]) 
    } else { 
     callNextMethod() 
    } 
} 
) 

setMethod("[", "foo", function(x, i, j, ..., drop) { 
    if (i == "x") { 
    return([email protected]) 
    } else { 
     if (i == "y") { 
     return([email protected]) 
     } 
    } 
} 
) 

b["distance"] 
# [1] 5 
b["x"] 
# [1] 3 
b["y"] 
# [1] 4