Có cờ gỡ lỗi có điều kiện mà tôi bỏ lỡ từ Matlab: dbstop if infnan
described here. Nếu được đặt, điều kiện này sẽ dừng thực thi mã khi gặp phải Inf
hoặc NaN
(IIRC, Matlab không có NA).Cách buộc lỗi nếu các giá trị không có giá trị (NA, NaN hoặc Inf) gặp phải
Làm thế nào tôi có thể đạt được điều này trong R một cách hiệu quả hơn kiểm tra tất cả các đối tượng sau mỗi hoạt động gán?
Tại thời điểm này, cách duy nhất tôi thấy để làm điều này là thông qua hacks như sau:
- Chèn một thử nghiệm sau khi tất cả những nơi mà những giá trị này có thể gặp phải (ví dụ như một bộ phận, nơi phân chia bởi 0 có thể xảy ra). Thử nghiệm sẽ là sử dụng
is.finite()
, described in this Q & A, trên mọi phần tử. - Sử dụng
body()
để sửa đổi mã để gọi một hàm riêng biệt, sau mỗi thao tác hoặc có thể chỉ mỗi phép gán, kiểm tra tất cả các đối tượng (và có thể tất cả các đối tượng trong mọi môi trường). - Sửa mã nguồn của R (?!?)
- Cố gắng sử dụng
tracemem
để xác định các biến đã thay đổi và chỉ kiểm tra những giá trị này có giá trị không tốt. - (Mới - xem chú thích 2) Sử dụng một số loại trình xử lý cuộc gọi/gọi lại để gọi hàm kiểm tra.
Tùy chọn thứ nhất là những gì tôi đang làm hiện nay. Điều này là tẻ nhạt, bởi vì tôi không thể đảm bảo tôi đã kiểm tra tất cả mọi thứ. Tùy chọn thứ 2 sẽ kiểm tra mọi thứ, ngay cả khi một đối tượng chưa được cập nhật. Đó là một sự lãng phí thời gian. Tùy chọn thứ 3 sẽ liên quan đến việc sửa đổi các nhiệm vụ của NA, NaN, và các giá trị vô hạn (+/- Inf), để một lỗi được tạo ra. Điều đó có vẻ như nó tốt hơn để lại R Core. Tùy chọn thứ 4 giống như thứ 2 - tôi cần một cuộc gọi đến một chức năng riêng biệt liệt kê tất cả các vị trí bộ nhớ, chỉ để ID những người đã thay đổi, và sau đó kiểm tra các giá trị; Tôi thậm chí không chắc chắn điều này sẽ làm việc cho tất cả các đối tượng, như một chương trình có thể làm một sửa đổi tại chỗ, mà có vẻ như nó sẽ không gọi chức năng duplicate
.
Có cách tiếp cận nào tốt hơn mà tôi bị thiếu không? Có lẽ một số công cụ thông minh của Mark Bravington, Luke Tierney, hoặc một cái gì đó tương đối cơ bản - một cái gì đó giống như một tham số options()
hoặc một lá cờ khi biên dịch R?
Ví dụ mã Dưới đây là một số mã ví dụ rất đơn giản để kiểm tra, kết hợp hàm addTaskCallback
do Josh O'Brien đề xuất. Mã không bị gián đoạn, nhưng lỗi xảy ra trong trường hợp đầu tiên, trong khi không có lỗi xảy ra trong trường hợp thứ hai (ví dụ: badDiv(0,0,FALSE)
không hủy bỏ). Tôi vẫn đang điều tra các cuộc gọi lại, vì điều này có vẻ đầy hứa hẹn.
badDiv <- function(x, y, flag){
z = x/y
if(flag == TRUE){
return(z)
} else {
return(FALSE)
}
}
addTaskCallback(stopOnNaNs)
badDiv(0, 0, TRUE)
addTaskCallback(stopOnNaNs)
badDiv(0, 0, FALSE)
Note 1. Tôi muốn được thỏa mãn với một giải pháp cho các hoạt động R tiêu chuẩn, mặc dù rất nhiều tính toán của tôi liên quan đến đối tượng sử dụng thông qua data.table
hoặc bigmemory
(ví dụ: bộ nhớ đĩa dựa trên ma trận ánh xạ). Chúng dường như có các hành vi bộ nhớ hơi khác so với các hoạt động ma trận chuẩn và data.frame.
Lưu ý 2. Ý tưởng gọi lại có vẻ hứa hẹn hơn một chút, vì điều này không yêu cầu tôi viết các hàm làm thay đổi mã R, ví dụ: qua ý tưởng body()
.
Lưu ý 3.Tôi không biết có hay không có một số cách đơn giản để kiểm tra sự hiện diện của các giá trị không hữu hạn, ví dụ: meta thông tin về các đối tượng mà chỉ mục nơi NA, Infs, vv được lưu trữ trong đối tượng, hoặc nếu chúng được lưu trữ tại chỗ. Cho đến nay, tôi đã thử gói inspect
của Simon Urbanek và không tìm thấy cách nào để loại bỏ sự hiện diện của các giá trị không phải số.
Theo dõi: Simon Urbanek đã chỉ ra trong nhận xét rằng thông tin đó không có sẵn dưới dạng thông tin meta cho các đối tượng.
Lưu ý 4. Tôi vẫn đang thử nghiệm các ý tưởng được trình bày. Ngoài ra, theo đề xuất của Simon, việc kiểm tra sự hiện diện của các giá trị không hữu hạn sẽ nhanh nhất trong C/C++; nên vượt qua cả mã R được biên dịch, nhưng tôi mở mọi thứ. Đối với các tập dữ liệu lớn, ví dụ: theo thứ tự 10-50GB, đây sẽ là một khoản tiết kiệm đáng kể so với việc sao chép dữ liệu. Người ta có thể nhận được những cải thiện hơn nữa thông qua việc sử dụng nhiều lõi, nhưng đó là một chút tiên tiến hơn.
Một số chức năng nguyên thủy đã chức năng này được xây dựng trong, tức là, họ trở về một lỗi hoặc một cảnh báo nếu được cung cấp hoặc cung cấp một tổ chức phi kết quả vô hạn. Lấy ví dụ, 'sin (Inf) '. Có lẽ đó là điều mà bạn có thể khám phá. –
Vâng, không phải luôn luôn trường hợp mà một Inf hoặc NaN * nên * dừng chức năng/mã của bạn (NA là một trường hợp riêng biệt bởi vì nó cố ý sử dụng tất cả các thời gian như là một 'phụ' hoặc 'đánh dấu'). Tôi thường chạy một số hoạt động mà sản xuất một số giá trị Inf, nói trong vùng tín hiệu thấp của một số ma trận. Tôi nghi ngờ bạn sẽ nhận được thông tin tốt hơn bằng cách sử dụng 'is.infinite' và/hoặc' is.nan' trên các biến nghi ngờ anyway. –
@CarlWitthoft Trong mã + kịch bản dữ liệu tôi hiện đang làm việc, giá trị vấn đề chính xác là ba - NA, NaN và Inf. Trong những trường hợp khác, tôi chắc chắn cần NA, nhưng không phải hôm nay. :) Tôi cần mã để hủy bỏ (nó khá tốn kém tính toán, b/c của khối lượng dữ liệu) ngay khi chúng xảy ra. Do đó, lý do tôi thực sự muốn kích hoạt một lỗi (hoặc ít nhất là một cảnh báo). – Iterator