В Matlab пропущен флаг условной отладки: dbstop, если описан infnan
здесь .Если установлено, это условие остановит выполнение кода при обнаружении Inf
или NaN
(IIRC, Matlab не имеет NA).
Как я могу добиться этого в R более эффективным способом, чем тестирование всех объектов после каждой операции присваивания?
На данный момент я вижу единственные способы сделать это с помощью хаков вроде следующего:
is.finite ()
, , описанных в этих вопросах и ответах , для каждого элемента. body ()
, чтобы изменить код для вызова отдельной функции после каждой операции или, возможно, только каждого назначения, которое проверяет все объекты (и, возможно, все объекты во всех средах). tracemem
для идентификации тех переменных, которые изменились, и проверить только их на наличие неверных значений. 1-й вариант - это то, что я делаю в настоящее время. Это утомительно, потому что я не могу гарантировать, что все проверил. Второй вариант проверит все, даже если объект не был обновлен. Это огромная трата времени. Третий вариант предполагает изменение присвоений NA, NaN и бесконечных значений (+/- Inf), так что возникает ошибка. Похоже, что лучше оставить R Core.Четвертый вариант похож на второй - мне понадобится вызов отдельной функции, перечисляющей все ячейки памяти, просто для идентификации тех, которые были изменены, а затем для проверки значений; Я даже не уверен, что это сработает для всех объектов, поскольку программа может выполнять модификацию на месте, которая, похоже, не будет вызывать функцию duplicate
.
Есть ли лучший подход, который мне не хватает? Может быть, какой-нибудь умный инструмент от Марка Бравингтона, Люка Тирни или что-то относительно простое - что-то вроде параметра options ()
или флага при компиляции R?
Пример кода Вот несколько очень простых пример кода для тестирования, включающий функцию addTaskCallback
, предложенную Джошем О'Брайеном. Код не прерывается, но ошибка возникает в первом сценарии, а во втором случае ошибки не возникает (т. Е. badDiv (0,0, FALSE)
не прерывается). Я все еще изучаю обратные вызовы, так как это выглядит многообещающим.
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)
Примечание 1. Я был бы удовлетворен решением для стандартных операций R, хотя во многих моих вычислениях используются объекты, используемые через data.table
или bigmemory
(т.е. disk- на основе матриц с отображением памяти). Похоже, что у них несколько иное поведение памяти, чем у стандартных операций matrix и data.frame.
Примечание 2. Идея обратных вызовов кажется немного более многообещающей, поскольку это не требует от меня написания функций, которые изменяют код R, например через идею body ()
.
Примечание 3. Я не знаю, есть ли какой-нибудь простой способ проверить наличие не конечных значений, напримерметаинформация об объектах, которая индексирует, где в объекте хранятся NAs, Infs и т. д., или если они хранятся на месте. До сих пор я пробовал пакет Саймона Урбанека inspect
и не нашел способа определить наличие нечисловых значений.
Продолжение: Саймон Урбанек указал в комментарии, что такая информация недоступна в качестве метаинформации для объектов.
Примечание 4. Я все еще тестирую представленные идеи. Кроме того, как предлагает Саймон, тестирование на наличие не конечных значений должно быть самым быстрым в C / C ++;это должно превосходить даже скомпилированный код R, но я открыт для всего. Для больших наборов данных, например порядка 10–50 ГБ, это должна быть значительная экономия по сравнению с копированием данных. Можно получить дополнительные улучшения за счет использования нескольких ядер, но это немного сложнее.