2015-12-31 19 views
12

Tôi có danh sách sau đâyDollar điều hành như là đối số chức năng cho sapply không làm việc như mong đợi

test_list=list(list(a=1,b=2),list(a=3,b=4)) 

và tôi muốn trích xuất tất cả các yếu tố với tên phần tử danh sách a.

tôi có thể làm được điều này thông qua

sapply(test_list,`[[`,"a") 

mà mang lại cho tôi kết quả chính xác

#[1] 1 3 

Khi tôi cố gắng cùng với Rs điều hành đô la $, tôi nhận được NULL

sapply(test_list,`$`,"a") 
#[[1]] 
#NULL 
# 
#[[2]] 
#NULL 

Tuy nhiên, nếu tôi sử dụng nó trên một phần tử duy nhất của test_list hoạt động như mong đợi

`$`(test_list[[1]],"a") 
#[1] 1 

Tôi có thiếu điều gì đó hiển nhiên ở đây không?

Trả lời

6

Từ những gì tôi đã có thể xác định đó là sự kết hợp của hai điều.

Đầu tiên, the second element of $ is matched but not evaluated so it cannot be a variable.

Thứ hai, khi đối số được chuyển đến các hàm, chúng được gán cho các biến tương ứng trong lệnh gọi hàm. Khi được chuyển đến sapply"a" được gán cho một biến và do đó sẽ không hoạt động với $ nữa. Chúng ta có thể thấy điều này bằng xảy ra bằng cách chạy

sapply("a", print) 
[1] "a" 
    a 
"a" 

Điều này có thể dẫn đến kết quả đặc biệt như thế này

sapply(test_list, function(x, a) {`$`(x, a)}) 
[1] 1 3 

đâu mặc dù a là một biến (mà đã thậm chí không được phân công) $ trận đấu nó vào tên của các phần tử trong danh sách.

+0

Câu trả lời rất thú vị! Về cơ bản nó cho thấy rằng đã có 'x =" a ";" $ "(test_list [[1]], x);' cho kết quả không chính xác. – cryo111

+0

Ngoài ra, tương tự như những gì bạn đã nói, '" $ "(test_list [[1]], a)' cho '1', mặc dù không có đối tượng' a' được định nghĩa. – cryo111

11

đánh giá vs none

[[ đánh giá đối số của nó trong khi $ không. L[[a]] nhận thành phần của L có tên được giữ trong biến a. $ chỉ cần chuyển tên đối số chính nó làm chuỗi ký tự để L$a tìm thành phần "a" của L. a không được coi là một biến giữ tên thành phần - chỉ là một chuỗi ký tự.

Dưới L[[b]] trả về thành phần của L tên "a" vì biến b có giá trị "a" trong khi L$b trả về componet của L tên "b" vì với cú pháp mà b không được coi như là một biến nhưng được coi là một chuỗi ký tự mà bản thân được thông qua.

L <- list(a = 1, b = 2) 
b <- "a" 
L[[b]] # same as L[["a"]] since b holds a 
## [1] 1 
L$b # same as L[["b"]] since b is regarded as a character string to be passed 
## [1] 2 

sapply

Bây giờ chúng ta hiểu sự khác biệt quan trọng bewteen $ và [[để xem những gì đang xảy ra với sapply xem xét ví dụ này. Chúng tôi đã thực hiện mỗi yếu tố của test_list vào một đối tượng "foo" và định nghĩa riêng của chúng tôi $.foo[[.foo phương pháp mà chỉ đơn giản hiển thị những gì R được qua phương pháp thông qua các name luận:

foo_list <- test_list 
class(foo_list[[1]]) <- class(foo_list[[2]]) <- "foo" 

"$.foo" <- "[[.foo" <- function(x, name) print(name) 

result <- sapply(foo_list, "$", "a") 
## "..." 
## "..." 

result2 <- sapply(foo_list, "[[", "a")  
## [1] "a" 
## [1] "a" 

gì đang xảy ra trong trường hợp thứ nhất là sapply được gọi là whatever$...... không được đánh giá nên sẽ tìm kiếm thành phần danh sách theo nghĩa đen là "..." và dĩ nhiên, không có thành phần như vậy để whatever$... là NULL do đó các giá trị NULL được hiển thị trong kết quả trong câu hỏi. Trong trường hợp thứ hai, whatever[[[...]] đánh giá thành whatever[["a"]] do đó kết quả quan sát được.

Các vấn đề liên quan