2012-03-05 38 views
11

Tôi đang cố sử dụng các giá trị gán trong một đối tượng trong danh sách. Những gì tôi muốn làm là thay đổi một số yếu tố. Ví dụ:Tại sao không gán() giá trị cho một phần tử danh sách hoạt động trong R?

x <- list() 
x$test <- 1 
assign("x$test", 2) 
x$test == 1 
    [1] TRUE 

Bạn nghĩ gì? Tôi cần phải sử dụng gán bởi vì tôi đang xây dựng một hàm sẽ lấy tên của các đối tượng trong danh sách (x) làm đầu vào.

+0

Lưu ý có sự khác biệt lớn giữa 'x $ test' và' x [['test']] '. Xem doc trên ['extract (..., drop = TRUE)'] (https://stat.ethz.ch/R-manual/R-devel/library/base/html/Extract.html) – smci

Trả lời

13

Có vẻ như bạn đã hết may mắn. Từ tập tin giúp đỡ:

'assign' không cử phương pháp phân công, vì vậy nó không thể được sử dụng để yếu tố tập các vectơ, tên, thuộc tính, vv

Lưu ý nhượng rằng đến một danh sách kèm theo hoặc khung dữ liệu thay đổi bản sao đính kèm chứ không phải đối tượng gốc: xem 'đính kèm' và 'với'.

Nếu bạn đang chuyển names(x) như là đầu vào, bạn không thể sử dụng:

nms <- names(x) 
for (n in nms) 
    x[[n]] <- 'new_value' 

Ngoài ra, bạn có ý định cho chức năng của bạn để sửa đổi một số biến toàn cầu? ví dụ:

x <- list(test=1) 

f <- function(...) 
    x$test <- 2 

f() # want x$test = 2 ?? 

Vì điều này sẽ không hoạt động (vấn đề phạm vi). Bạn có thể làm cho nó hoạt động với một số bước chân (<<-), nhưng điều này thường được coi là thực hành xấu vì nó dễ dàng để intrtoduce lỗi không chủ ý vào mã của bạn.

Nếu bạn có thể đưa ra ví dụ về lý do bạn muốn chức năng này/mục đích sẽ phục vụ, chúng tôi có thể giúp bạn tìm ra giải pháp thay thế.

+0

Tuyệt vời, cảm ơn rất nhiều - Tôi không biết rằng tôi có thể sử dụng cú pháp [[n]], điều đó là hoàn toàn đủ. Thực sự đánh giá cao thông tin. – mike

8

Xem những gì sẽ xảy ra khi bạn gán cho "x $ test":

x <- list() 
x$test <- 1 
assign("x$test", 2) 
ls() 
[1] "x"  "x$test" 

Yếu tố "thử nghiệm" trong "x" vẫn là 1, và bạn giải nén nó với x$test nhưng get("x$test") sẽ là giá trị 2 từ cái tên đó.

Tại sao không chỉ sử dụng tên trực tiếp? I E.

this.name <- "test" 
x[[this.name]] <- 2 
+0

Tôi không biết tại sao câu trả lời khác đã được chấp nhận, nhưng như mdsumner nói, tại sao không sử dụng tên trực tiếp? hoạt động hoàn hảo. – user1052080

+0

assign() cho phép bạn chỉ định môi trường trong đó nhiệm vụ xảy ra, có thể rất hữu ích. Điều này trái ngược với << - chỉ gán cho môi trường toàn cầu. Vì vậy, x [[name]] không phải là chung một giải pháp như gán (x $ tên, giá trị, envir = my_env) sẽ được. –

1

giải pháp khác là:

x <- list() 
x$test <- 1 
assign("x$test", 2) 
x$test == 1 
TRUE 
eval(parse(text="x$test<-2")) 
x$test == 1 
FALSE 

Lệnh eval(parse(text="")) có thể rất hữu ích trong bối cảnh này.

Trân trọng

+4

Để diễn giải Thomas Lumley: "Nếu câu trả lời là phân tích cú pháp() bạn thường nên suy nghĩ lại câu hỏi." Tránh các cấu trúc như thế này mọi lúc nếu có giải pháp hợp lý hơn. Ở đây giải pháp đó là '[[' –

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