2012-03-15 19 views
13

Một bài đăng trên đây một ngày trở lại đây khiến tôi tự hỏi cách gán giá trị cho nhiều đối tượng trong môi trường toàn cục từ bên trong một hàm. Đây là nỗ lực của tôi khi sử dụng lapply (assign có thể an toàn hơn <<- nhưng tôi chưa bao giờ thực sự sử dụng nó và không quen thuộc với nó).Chỉ định nhiều đối tượng cho .GlobalEnv từ bên trong một hàm

#fake data set 
df <- data.frame(
    x.2=rnorm(25), 
    y.2=rnorm(25), 
    g=rep(factor(LETTERS[1:5]), 5) 
) 

#split it into a list of data frames 
LIST <- split(df, df$g) 

#pre-allot 5 objects in R with class data.frame() 
V <- W <- X <- Y <- Z <- data.frame() 

#attempt to assign the data frames in the LIST to the objects just created 
lapply(seq_along(LIST), function(x) c(V, W, X, Y, Z)[x] <<- LIST[[x]]) 

Vui lòng rút ngắn bất kỳ/tất cả các phần mã của tôi để thực hiện công việc này (hoặc hoạt động tốt hơn/nhanh hơn).

+3

Câu hỏi này hoặc bất kỳ câu trả lời nào cho nó phải đi kèm với một "Trẻ em lớn, đừng làm điều này ở nhà!" từ chối trách nhiệm. Như bạn có thể biết, các bài tập toàn cầu trong các chức năng là một công thức cho thảm họa, hoặc "cuộc sống của một ngọn núi lửa" để trích dẫn Richard Burns (http://www.burns-stat.com/pages/Tutor/R_inferno.pdf) – flodel

+0

@flodel Tôi không có lập trình để bạn có thể giải thích ngắn gọn vấn đề với việc chỉ định là gì? –

+0

Vì vậy, tôi đọc phần bạn đã trích dẫn. Điều đó có vẻ thông minh cho mã cho tiêu dùng công cộng nhưng không phải cho mã cá nhân. Bạn có thể thấy một cách để đạt được điều này ảnh hưởng không? –

Trả lời

22

Bạn nói đúng rằng assign() là công cụ thích hợp cho công việc. Đối số envir của bạn cho phép bạn kiểm soát chính xác vị trí diễn ra - kiểm soát không có sẵn với <- hoặc <<-.

Vì vậy, ví dụ, để gán giá trị của X đến một đối tượng tên là NAME trong môi trường toàn cầu, bạn sẽ làm gì:

assign("NAME", X, envir = .GlobalEnv) 

Trong trường hợp của bạn:

df <- data.frame(
    x.2=rnorm(25), 
    y.2=rnorm(25), 
    g=rep(factor(LETTERS[1:5]), 5) 
) 
LIST <- split(df, df$g) 
NAMES <- c("V", "W", "X", "Y", "Z") 

lapply(seq_along(LIST), 
     function(x) { 
      assign(NAMES[x], LIST[[x]], envir=.GlobalEnv) 
     } 
) 

ls() 
[1] "df" "LIST" "NAMES" "V"  "W"  "X"  "Y"  "Z"  
+0

Cảm ơn. Tôi biết '<< - 'là hình thức xấu nhưng đã lười biếng. Tôi sẽ đi vào thói quen sử dụng 'assign'. Tôi thực sự đã có chính xác những gì bạn làm tại một thời điểm nhưng nghĩ rằng tôi không nên đặt dấu ngoặc kép xung quanh các đối tượng như tôi đã trước khi phân bổ chúng. Điều này dễ dàng hơn. –

+0

Vâng. Sử dụng 'assign()' là một trong những thứ trông giống như một bướu để vượt qua trước khi bạn thử nó, nhưng một khi bạn làm thế, bạn tự hỏi tại sao bạn lại có bất kỳ chút do dự nào ngay từ đầu. –

+0

+1 - vàng. Tôi đã phải gán tất cả các đối tượng trong một môi trường vào môi trường toàn cầu vừa nãy, và giải pháp này đã cứu tôi phải suy nghĩ. – ricardo

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