2013-02-01 29 views
8

Chức năng rapply ít được sử dụng phải là giải pháp hoàn hảo cho nhiều sự cố (chẳng hạn như this one). Tuy nhiên, nó để lại hàm do người dùng viết f mà không có khả năng biết nó ở đâu trong cây.Nhận tên phần tử trong rapply

Có cách nào để chuyển tên của phần tử trong danh sách lồng nhau đến f trong cuộc gọi rapply không? Thật không may, rapply gọi .Internal khá nhanh chóng.

Trả lời

1

Tôi đã gặp khó khăn với danh sách lồng nhau với độ sâu tùy ý gần đây. Cuối cùng, tôi đã đưa ra quyết định chấp nhận nhiều hơn hoặc ít hơn trong trường hợp của tôi. Nó không phải là câu trả lời trực tiếp cho câu hỏi của bạn (không sử dụng số rapply), nhưng có vẻ như đang giải quyết cùng một vấn đề. Tôi hy vọng nó có thể giúp đỡ một số.

Thay vì cố truy cập tên các phần tử danh sách bên trong rapply Tôi đã tạo vectơ tên và truy vấn nó cho các phần tử.

# 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))) 

Tạo vector tên là một điều khó khăn trong trường hợp của tôi. Cụ thể, tên của các phần tử danh sách phải an toàn, tức là không có biểu tượng ..

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" 

Bước tiếp theo là truy cập phần tử danh sách theo tên chuỗi. Tôi thấy không có gì tốt hơn bằng cách sử dụng tập tin tạm thời.

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

Đây f chỉ trả về giá trị của x, nơi x là một chuỗi với tên đầy đủ của nguyên tố danh sách.

Cuối cùng, chúng tôi có thể truy vấn danh sách theo cách giả đệ quy.

sapply(node.names, f) 
0

Đề cập đến câu hỏi Find the indices of an element in a nested list?, bạn có thể viết:

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)) 
} 

sau đó,

> 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 
Các vấn đề liên quan