2013-03-27 14 views
13

Trong khi xây dựng các biểu thức để đặt trong số j -loại cuộc gọi [.data.table, sẽ rất hữu ích khi có thể kiểm tra và phát xung quanh với nội dung của .SD.Có thể .SD được xem từ trình duyệt trong [.data.table() không?

nỗ lực ngây thơ này không hoạt động ...

library(data.table) 
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9) 

DT[, browser(), by=x] 
# Called from: `[.data.table`(DT, , browser(), by = x) 
Browse[1]> 
Browse[1]> .SD 
# NULL data.table 

... mặc dù một biến có tên .SD và một số người khác liên quan đến việc tập hợp con data.table hiện tại đều hiện diện trong môi trường địa phương

Browse[1]> ls(all.names = TRUE) 
# [1] ".BY"  ".GRP"  ".I"  ".iSD"  ".N"  ".SD"  
# [7] "Cfastmean" "mean"  "print"  "x"   
Browse[1]> .N 
# [1] 3 
Browse[1]> .I 
# [1] 4 5 6 

Sử dụng .I, tôi có thể xem một cái gì đó giống như +/- .SD, nhưng nó sẽ được tốt đẹp để có thể truy cập trực tiếp giá trị của nó:

Browse[1]> DT[.I] 
# x y v 
# 1: b 1 4 
# 2: b 3 5 
# 3: b 6 6 

Câu hỏi của tôi: Tại sao giá trị kỳ vọng của .SD không trực tiếp có sẵn từ bên trong một cuộc gọi browser() (trong khi .I, .N, .GRP.BY là)? Có cách nào khác để truy cập vào giá trị của .SD không?

+2

Tôi đã thắng der, tại thời điểm 'browser()' được gọi, là '.SD' thực sự có chứa bất cứ thứ gì? 'str (.SD)' hiển thị 'Lớp dữ liệu 'data.table' và 'data.frame': \t 0 obs. của 0 biến' v.v. –

+0

@GavinSimpson - Tôi nghĩ bạn có thể đang ở trên một thứ gì đó ở đó. Câu trả lời một phần tôi vừa thêm vào có vẻ như bằng chứng bổ sung theo hướng đó. Tôi cũng tự hỏi nếu đánh giá chậm trễ của '.SD' là bằng cách nào đó có liên quan. –

Trả lời

14

cập nhật trong ánh sáng của bình luận Matthew Dowle của:

Nó chỉ ra rằng .SD là, trong nội bộ, môi trường mà trong đó tất cảj biểu thức được đánh giá, kể cả những người mà không tham khảo một cách rõ ràng .SD ở tất cả . Điền nó với tất cả các cột của DT cho mỗi tập con của DT không phải là giá rẻ, thời gian, do đó, [.data.table() sẽ không làm như vậy trừ khi nó thực sự cần. Thay vào đó, sử dụng tuyệt vời đánh giá lười biếng của R đối số, nó xem trước biểu thức j không đánh giá và chỉ thêm .SD cột được tham chiếu trong đó. Nếu chính nó được đề cập là .SD, nó sẽ thêm tất cả các cột của DT.

Vì vậy, để xem .SD, chỉ cần bao gồm một số tham chiếu đến nó trong j -expression. Đây là một trong nhiều biểu thức mà sẽ làm việc:

library(data.table) 
DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9) 

## This works 
DT[, if(nrow(.SD)) browser(), by=x] 
# Called from: `[.data.table`(DT, , if (nrow(.SD)) browser(), by = x) 
Browse[1]> .SD 
# y v 
# 1: 1 1 
# 2: 3 2 
# 3: 6 3 

Và dưới đây là một vài chi tiết:

DT[,{.SD; browser()}, by=x] 
DT[,{browser(); .SD}, by=x] ## Notice that order doesn't matter 

Để xem cho chính mình rằng .SD chỉ tải các cột cần thiết cho j -expression, chạy các mỗi lần lượt (nhập .SD khi nhập môi trường trình duyệt và Q để rời khỏi nó và quay lại dòng lệnh bình thường):

DT[, {.N * y ; browser()}, by=x] 
DT[, {v^2 ; browser()}, by=x] 
DT[, {y*v ; browser()}, by=x] 
+1

FWIW, 'DT [, {. SD; trình duyệt()}, bởi = x] 'cũng hoạt động. –

+0

Mục 2.1 của [dữ liệu.table' FAQ] (http://datatable.r-forge.r-project.org/datatable-faq.pdf) đề cập đến sự chậm lớn mà sử dụng '.SD' có thể đòi hỏi. –

+0

Josh, không thực sự. phần 2.1 của Câu hỏi thường gặp đề xuất sử dụng '.SD', nhưng * không * với' with = FALSE'. ** ** Đối tượng SD được triển khai hiệu quả trong nội bộ và hiệu quả hơn so với truyền đối số cho hàm. Tuy nhiên, đừng làm điều này: 'DT [,. SD [," sales ", with = FALSE], bởi = grp]' ** **. – Arun

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