2015-10-07 16 views
27

Tôi muốn sửa đổi một data.table trong một hàm. Nếu tôi sử dụng tính năng := trong chức năng, kết quả chỉ được in cho cuộc gọi thứ hai.Các đối tượng dữ liệu có thể không được in sau khi được trả về từ hàm

Nhìn vào hình minh họa sau đây:

library(data.table) 
mydt <- data.table(x = 1:3, y = 5:7) 

myfunction <- function(dt) { 
    dt[, z := y - x] 
    dt 
} 

Khi tôi gọi chỉ có chức năng, bảng được không in (mà là hành vi tiêu chuẩn Tuy nhiên, nếu tôi lưu lại data.table vào một đối tượng mới. , nó không được in ở cuộc gọi đầu tiên, duy nhất cho một giây.

myfunction(mydt) # nothing is printed 
result <- myfunction(mydt) 
result # nothing is printed 
result # for the second time, the result is printed 
mydt                  
# x y z 
# 1: 1 5 4 
# 2: 2 6 4 
# 3: 3 7 4 

Ông có thể giải thích tại sao điều này xảy ra và làm thế nào để ngăn chặn nó?

+4

đọc này: https://github.com/Rdatatable/data.table/blob/master /NEWS.md#bug-fixes-3. BUG đầu tiên đã được sửa trong phiên bản 1.9.6 –

+0

Xem phần 2.23 của câu hỏi thường gặp 'data.table' (' vignette ("datatable-faq", package = "data.table") ') – Uwe

Trả lời

29

David Arenburg đề cập trong một comment, câu trả lời có thể được tìm thấy here. Đã xảy ra lỗi trong phiên bản 1.9.6 nhưng bản sửa lỗi đã giới thiệu nhược điểm này.

Bạn nên gọi DT[] ở cuối chức năng để ngăn chặn hành vi này.

myfunction <- function(dt) { 
    dt[, z := y - x][] 
} 
myfunction(mydt) # prints immediately 
# x y z 
# 1: 1 5 4 
# 2: 2 6 4 
# 3: 3 7 4 
+5

' DT [] 'chỉ cần khi in dữ liệu. , do đó, khi sử dụng các hàm ': =' hoặc 'set *' – jangorecki

0

Tôi xin lỗi nếu tôi không được phép gửi một cái gì đó ở đây là không phải là một câu trả lời , nhưng bài của tôi là quá dài cho một nhận xét.

Tôi muốn chỉ ra giải pháp của janosdivenyi rằng thêm một trailing []-dt không phải lúc nào cung cấp cho các kết quả mong đợi (ngay cả khi sử dụng data.table 1.9.6 hoặc 1.10.4) như tôi làm dưới đây.

Các ví dụ dưới đây cho thấy rằng nếu dt là dòng cuối cùng trong hàm người ta có hành vi mong muốn mà không cần sự hiện diện của trailing [], nhưng nếu dt không phải là trên dòng cuối cùng trong hàm sau đó một trailing [] là cần thiết để có được hành vi mong muốn.

Ví dụ đầu tiên cho thấy rằng không có đuôi [] trên dt chúng tôi nhận được hành vi mong đợi khi dt là trên dòng cuối cùng của hàm

mydt <- data.table(x = 1:3, y = 5:7) 

myfunction <- function(dt) { 
    df <- 1 
    dt[, z := y - x] 
} 

myfunction(mydt) # Nothing printed as expected 

mydt # Content printed as desired 
## x y z 
## 1: 1 5 4 
## 2: 2 6 4 
## 3: 3 7 4 

Thêm một trailing [] trên dt cho hành vi bất ngờ

mydt <- data.table(x = 1:3, y = 5:7) 

myfunction <- function(dt) { 
    df <- 1 
    dt[, z := y - x][] 
} 

myfunction(mydt) # Content printed unexpectedly 
## x y z 
## 1: 1 5 4 
## 2: 2 6 4 
## 3: 3 7 4 

mydt # Content printed as desired 
## x y z 
## 1: 1 5 4 
## 2: 2 6 4 
## 3: 3 7 4 

Di chuyển df <- 1 đến sau dt không có dấu sau [] cho unexpec ted hành vi

mydt <- data.table(x = 1:3, y = 5:7) 

myfunction <- function(dt) { 
    dt[, z := y - x] 
    df <- 1 
} 

myfunction(mydt) # Nothing printed as expected 

mydt # Nothing printed unexpectedly 

Moving df <- 1 sau khi dt với một trailing [] cung cấp cho các dự hành vi

mydt <- data.table(x = 1:3, y = 5:7) 

myfunction <- function(dt) { 
    dt[, z := y - x][] 
    df <- 1 
} 

myfunction(mydt) # Nothing printed as expected 

mydt # Content printed as desired 
## x y z 
## 1: 1 5 4 
## 2: 2 6 4 
## 3: 3 7 4 
+1

Tôi nghĩ bạn đang bối rối một chút về cách các hàm hoạt động. Tất cả các hàm trả về một giá trị. Nếu bạn không viết câu lệnh 'return (x)' rõ ràng, thì giá trị cuối cùng trong hàm được trả về. 'df <- 1' trả về giá trị' 1' invisibly', trong khi 'DT [, x: = y] []' trả về 'DT', được in. – Frank

+1

Cảm ơn lời giải thích đó. Tôi không nhận ra. Tôi đoán đó là "trở lại vô hình" bit mà đã cho tôi. Tôi cũng bị nhầm lẫn bởi khía cạnh "sao chép theo tham chiếu" của các bảng dữ liệu. Tôi đã dành thời gian chơi với những ví dụ đó để cố gắng hiểu chúng. Bây giờ bạn thấy lý do tại sao tôi không trả lời câu hỏi trên diễn đàn này :-) – Paul

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