2009-08-21 27 views
26

Nhiều sách và hướng dẫn R giới thiệu bắt đầu bằng cách thực hành đính kèm một số data.frame để bạn có thể gọi các biến theo tên. Tôi luôn thấy thuận lợi khi gọi các biến có ký hiệu $ hoặc cắt khung vuông [,2]. Bằng cách đó tôi có thể sử dụng nhiều số data.frame mà không gây nhầm lẫn cho chúng và/hoặc sử dụng lặp lại để liên tục gọi các cột quan tâm. Tôi nhận thấy Google gần đây đã đăng coding guidelines for R trong đó bao gồm dòngBạn có sử dụng attach() hoặc gọi các biến theo tên hoặc cắt không?

1) đính kèm: tránh sử dụng nó

Làm thế nào để mọi người cảm thấy về thực tiễn này?

Trả lời

25

Tôi không bao giờ sử dụng kèm theo. withwithin là bạn của bạn.

Ví dụ mã:

> N <- 3 
> df <- data.frame(x1=rnorm(N),x2=runif(N)) 
> df$y <- with(df,{ 
    x1+x2 
}) 
> df 
      x1   x2   y 
1 -0.8943125 0.24298534 -0.6513271 
2 -0.9384312 0.01460008 -0.9238312 
3 -0.7159518 0.34618060 -0.3697712 
> 
> df <- within(df,{ 
    x1.sq <- x1^2 
    x2.sq <- x2^2 
    y <- x1.sq+x2.sq 
    x1 <- x2 <- NULL 
}) 
> df 
      y  x2.sq  x1.sq 
1 0.8588367 0.0590418774 0.7997948 
2 0.8808663 0.0002131623 0.8806532 
3 0.6324280 0.1198410071 0.5125870 

Edit: hadley đề cập đến chuyển đổi trong các ý kiến. đây là một số mã:

> transform(df, xtot=x1.sq+x2.sq, y=NULL) 
     x2.sq  x1.sq  xtot 
1 0.41557079 0.021393571 0.43696436 
2 0.57716487 0.266325959 0.84349083 
3 0.04935442 0.004226069 0.05358049 
+3

'transform' là một biến thể hữu ích khác bên trong. – hadley

+1

Thực ra tôi nhận thấy rằng không giống như 'attach()', 'with()' không "giải quyết thông qua" hàm ". Đầu tiên thiết lập 'printx <- function {print (x)}'. Bây giờ, 'với (danh sách (x = 42), printx())' thất bại mặc dù 'với (danh sách (x = 42), in (x))' và 'đính kèm (danh sách (x = 42)); printx() 'thành công! :( –

3

Tôi không thích sử dụng attach(), vì quá dễ dàng để chạy một lô mã nhiều lần mỗi lần gọi attach(). Khung dữ liệu được thêm vào đường dẫn tìm kiếm mỗi lần, mở rộng nó một cách không cần thiết. Tất nhiên, thực hành lập trình tốt cũng là detach() ở cuối khối mã, nhưng điều đó thường bị lãng quên.

Thay vào đó, tôi sử dụng xxx $ y hoặc xxx [, "y"]. Nó minh bạch hơn.

Một khả năng khác là sử dụng đối số dữ liệu có sẵn trong nhiều hàm cho phép các biến riêng lẻ được tham chiếu trong khung dữ liệu. ví dụ: lm(z ~ y, data=xxx).

+0

Thỉnh thoảng tôi đang gọi từ các khung dữ liệu khác nhau và các biến toàn cầu, và hệ thống này có nghĩa là không bao giờ thực hiện tính toán sai. – Michelle

8

Vấn đề chính khi đính kèm là nó có thể dẫn đến hành vi không mong muốn. Giả sử bạn có một đối tượng có tên xyz trong vùng làm việc của bạn. Bây giờ bạn đính kèm dataframe abc trong đó có một cột có tên là xyz. Nếu mã của bạn tham chiếu đến xyz, bạn có thể đảm bảo đó là tham chiếu đến đối tượng hoặc cột dataframe không? Nếu bạn không sử dụng đính kèm thì nó rất dễ dàng. chỉ xyz đề cập đến đối tượng. abc $ xyz đề cập đến cột của khung dữ liệu.

Một trong những lý do chính đính kèm được sử dụng thường xuyên trong sách giáo khoa là nó rút ngắn mã.

+0

Tôi đã nhận thấy rằng một số sách giáo khoa nói "không làm điều này, đính kèm đang được sử dụng để đơn giản hóa các ví dụ". – Michelle

13

Tôi rất thích sử dụng with để có được tương đương với attach trên một lệnh duy nhất:

with(someDataFrame, someFunction(...)) 

này cũng dẫn một cách tự nhiên để tạo thành một nơi subset là đối số đầu tiên:

with(subset(someDataFrame, someVar > someValue), 
     someFunction(...)) 

mà làm cho nó khá rõ ràng rằng chúng tôi hoạt động trên một lựa chọn dữ liệu. Và mặc dù nhiều chức năng mô hình có cả hai đối số datasubset, việc sử dụng ở trên phù hợp hơn vì nó cũng áp dụng cho những chức năng không có đối số datasubset.

7

"Đính kèm" là một sự cám dỗ tà ác.Các chỉ nơi mà nó hoạt động tốt là trong thiết lập lớp học nơi mà một trong những được đưa ra một dataframe duy nhất và dự kiến ​​sẽ viết dòng mã để làm các phân tích trên đó một dataframe. Người dùng sẽ không bao giờ có thể sử dụng lại dữ liệu đó sau khi gán xong và được giao.

Tuy nhiên, trong thế giới thực, có thể thêm nhiều khung dữ liệu vào bộ sưu tập dữ liệu trong một dự án cụ thể. Hơn nữa, người ta thường sao chép và dán các khối mã được sử dụng cho một cái gì đó tương tự. Thường thì người ta vay mượn từ một cái gì đó đã làm một vài tháng trước và không thể nhớ được sắc thái của những gì đã được gọi từ đâu. Trong những trường hợp này, một người bị chết đuối bởi việc sử dụng "đính kèm" trước đó.

2

Trong khi tôi cũng không thích sử dụng attach(), nó có vị trí của nó khi bạn cần duy trì một đối tượng (trong trường hợp này là data.frame) trong suốt quá trình sử dụng chương trình của bạn. Thay vì truyền đối tượng vào mọi hàm R sử dụng nó, tôi nghĩ thuận tiện hơn là giữ nó ở một nơi và gọi các phần tử của nó khi cần thiết.

Điều đó nói rằng, tôi sẽ chỉ sử dụng nếu tôi biết tôi có bao nhiêu bộ nhớ và chỉ khi tôi đảm bảo rằng tôi detach() này data.frame khi nó nằm ngoài phạm vi.

Tôi có ý nghĩa không?

3

Giống như Leoni đã nói, withwithin là những sản phẩm thay thế hoàn hảo cho attach, nhưng tôi sẽ không loại bỏ hoàn toàn nó. Tôi sử dụng nó đôi khi, khi tôi đang làm việc trực tiếp tại dấu nhắc R và muốn kiểm tra một số lệnh trước khi viết chúng trên một kịch bản. Đặc biệt khi thử nghiệm nhiều lệnh, attach có thể là một thay thế thú vị, thuận tiện và thậm chí vô hại hơn đối với withwithin, kể từ sau khi bạn chạy attach, dấu nhắc lệnh là rõ ràng để bạn viết đầu vào và xem kết quả đầu ra.

Chỉ cần đảm bảo detach dữ liệu của bạn sau khi bạn hoàn tất!

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