Cuối cùng tôi đã tìm ra câu trả lời cho câu hỏi này (sau vài năm). Tất cả các ý kiến và câu trả lời đề nghị thêm data.table
-Depends
hoặc Imports
, nhưng điều này là không chính xác; gói không phụ thuộc vào data.table
và đó có thể là bất kỳ gói giả thuyết, không chỉ data.table, có nghĩa là đưa đến kết luận hợp lý, đề nghị sẽ đòi hỏi thêm tất cả các gói có thể Depends
- kể từ khi sự phụ thuộc được cung cấp bởi người sử dụng cung cấp instruction
, không phải bởi chức năng được cung cấp bởi gói. Thay vào đó, về cơ bản, đó là vì gọi tới eval
được thực hiện trong vùng tên của gói và điều này không bao gồm các chức năng được cung cấp bởi các gói khác. Tôi cuối cùng giải quyết điều này bằng cách xác định môi trường toàn cầu trong eval
gọi:
myFunc = function(instruction) {
eval(parse(text=instruction), envir=globalenv())
}
Tại sao các công trình này
Điều này làm cho eval
chức năng để được thực hiện trong môi trường đó sẽ bao gồm các gói cần thiết trong việc tìm kiếm con đường.
Trong trường hợp data.table
nó đặc biệt khó khăn để gỡ lỗi vì sự phức tạp của hàm quá tải. Trong trường hợp này, thủ phạm không phải là thực sự là :=
chức năng, nhưng [
chức năng. Các lỗi :=
là một cá trích đỏ.Tại thời điểm viết bài, các :=
chức năng trong data.table
được định nghĩa như thế này:
https://github.com/Rdatatable/data.table/blob/348c0c7fdb4987aa6da99fc989431d8837877ce4/R/data.table.R#L2561
":=" <- function(...) stop('Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":=").')
Vậy là xong. Điều đó có nghĩa là: mọi cuộc gọi đến :=
là một chức năng bị dừng với thông báo lỗi, vì đây không phải là cách tác giả dự định sử dụng :=
. Thay vào đó, :=
thực sự chỉ là từ khóa được giải thích bởi hàm [
trong data.table
.
Nhưng những gì xảy ra ở đây: nếu chức năng [
không được ánh xạ một cách chính xác lên phiên bản theo quy định của data.table
, và thay vào đó là ánh xạ tới các cơ sở [
, sau đó chúng tôi có một vấn đề - vì nó không thể xử lý :=
và do đó nó được coi là một hàm và kích hoạt thông báo lỗi. Vì vậy, chức năng thủ phạm là [.data.table
- toán tử khung quá tải.
gì đang xảy ra là trong gói mới của tôi (chứa myFuncInPackage
), khi nó đi để đánh giá mã, nó giải quyết các [
chức năng với chức năng cơ sở [
thay vì để data.table
's [
chức năng. Nó cố gắng để đánh giá :=
là một hàm không được tiêu thụ bởi [
vì nó không phải là đúng [
, vì vậy :=
được chuyển thành hàm thay vì giá trị thành data.table
vì không có vùng tên (data.table
) hoặc là thấp hơn trong hệ thống phân cấp search()
. trong bối cảnh này, :=
không hiểu và vì vậy nó được đánh giá là một chức năng, do đó kích hoạt các thông báo lỗi trong mã data.table
trên.
Khi bạn chỉ định eval xảy ra trong toàn cầu môi trường, nó giải quyết một cách chính xác hàm [
đến [.data.table
và :=
được diễn giải chính xác
Ngẫu nhiên, bạn cũng có thể sử dụng điều này nếu bạn đang đi qua không phải là một chuỗi ký tự nhưng một khối mã (tốt hơn) để eval()
bên trong một gói:
eval(substitute(instruction), envir=globalenv())
Ở đây, substitute
ngăn ngừa sự instruction
từ việc phân tích cú pháp (không chính xác) trong vùng tên gói tại giai đoạn đánh giá-đối số, để nó làm cho nó trở lại nguyên vẹn với globalenv, nơi nó có thể được đánh giá đúng với các hàm được yêu cầu tại chỗ.
Bạn đã làm theo lời khuyên trong [Câu hỏi thường gặp 6.9] (http://cran.r-project.org/web/packages/data.table/vignettes/datatable-faq.pdf) chưa? Ngoài ra, việc sử dụng 'eval (parse())' không được khuyến khích. – Roland
@Roland Thêm data.table vào Depends giải quyết nó ... nhưng dẫn đến một vấn đề: gói của tôi không thực sự phụ thuộc vào data.table; trên thực tế, nó hoàn toàn không liên quan. Như trong ví dụ này, nó chỉ có một hàm, 'myFunc' - không có dữ liệu. Nhưng nó không thể được sử dụng với data.table mà không cần thêm nó vào Depends ... – nsheff
@Roland, tôi biết, 'eval (parse())' không được khuyến khích, và đây là một ví dụ vô nghĩa, nhưng câu hỏi vẫn đứng vững. ..trong một số trường hợp, tôi không thể đi lại. – nsheff