2013-02-01 11 views
8

Mała używana funkcja rapply powinna być idealnym rozwiązaniem wielu problemów (takich jak this one). Pozostawia jednak zapisaną przez użytkownika funkcję f bez możliwości sprawdzenia, gdzie znajduje się w drzewie.Pobierz nazwy elementów w rapply

Czy istnieje sposób przekazania nazwy elementu na liście zagnieżdżonej do f w wywołaniu rapply? Niestety, rapply dość szybko wywołuje .Internal.

Odpowiedz

1

Niedawno zmagałem się z zagnieżdżonymi listami z dowolną głębią. W końcu doszłam do mniej lub bardziej akceptowalnej decyzji w moim przypadku. Nie jest to bezpośrednia odpowiedź na twoje pytanie (no rapply), ale wydaje się, że rozwiązuje ten sam rodzaj problemów. Mam nadzieję, że może to być pomocne.

Zamiast próbować uzyskać dostęp do nazw elementów listy wewnątrz rapply wygenerowałem wektor nazw i zapytałem o elementy.

# Sample list with depth of 3 
mylist <- list(a=-1, b=list(A=1,B=2), c=list(C=3,D=4, E=list(F=5,G=6))) 

Generowanie wektorów nazw jest w moim przypadku trudne. W szczególności nazwy elementów listy powinny być bezpieczne, tj. Bez symbolu ..

list.names <- strsplit(names(unlist(mylist)), split=".", fixed=TRUE) 
node.names <- sapply(list.names, function(x) paste(x, collapse="$")) 
node.names <- paste("mylist", node.names, sep="$") 
node.names 

[1] "mylist$a"  "mylist$b$A" "mylist$b$B" "mylist$c$C" "mylist$c$D" "mylist$c$E$F" 
[7] "mylist$c$E$G" 

Następnym krokiem jest uzyskanie dostępu do elementu listy według nazwy ciągu. Nie znalazłem nic lepszego niż użycie pliku tymczasowego.

f <- function(x){ 
    fname <- tempfile() 
    cat(x, file=fname) 
    source(fname)$value 
} 

Tutaj f prostu zwraca wartość x, gdzie x jest ciągiem z pełną nazwą elementu listy.

Wreszcie możemy wyświetlić listę zapytań w pseudorekursywny sposób.

sapply(node.names, f) 
0

Odnosząc się do kwestii Find the indices of an element in a nested list?, można napisać:

rappply <- function(x, f) { 
    setNames(lapply(seq_along(x), function(i) { 
    if (!is.list(x[[i]])) f(x[[i]], .name = names(x)[i]) 
    else rappply(x[[i]], f) 
    }), names(x)) 
} 

wtedy,

> mylist <- list(a = 1, b = list(A = 1, B = 2), c = list(C = 1, D = 3)) 
> 
> rappply(mylist, function(x, ..., .name) { 
+ switch(.name, "a" = 1, "C" = 5, x) 
+ }) 
$a 
[1] 1 

$b 
$b$A 
[1] 1 

$b$B 
[1] 2 


$c 
$c$C 
[1] 5 

$c$D 
[1] 3 
Powiązane problemy