2013-07-06 5 views
3

Когда i содержит NA, эта конкретная строка не возвращается. Я не уверен, что это намеченное поведение или не так ли?NA в выражении `i` data.table (возможная ошибка)

require(data.table) 
x = data.table(a=c(NA, 1:3, NA))  
x[a>0]  
    a 
1: 1 
2: 2 
3: 3 

x[!(a>0)] 
    a 
1: NA 
2: NA 

x[a<0] 
Empty data.table (0 rows) of 1 col: a 

x[!(a<0)] 
    a 
1: NA 
2: 1 
3: 2 
4: 3 
5: NA 

> sessionInfo() 
R version 2.15.2 (2012-10-26) 
Platform: x86_64-unknown-linux-gnu (64-bit) 

locale: 
    [1] LC_CTYPE=en_US.UTF-8  LC_NUMERIC=C    
    [3] LC_TIME=en_US.UTF-8  LC_COLLATE=en_US.UTF-8  
    [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 
    [7] LC_PAPER=C     LC_NAME=C     
    [9] LC_ADDRESS=C    LC_TELEPHONE=C    
    [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C  

attached base packages: 
    [1] stats  graphics grDevices utils  datasets methods base  

other attached packages: 
    [1] data.table_1.8.8 
+1

Интересно ... Могу ли я предложить вам использовать 'а = с (NA, 1: 3 , NA) 'в вашем примере? Наличие такого длинного примера не является полезным или актуальным. – flodel

+1

Иными словами, 'x [as.logical (a)]' и 'x [!! as.logical (a)]' не дают того же результата. Соблазн назвать это ошибкой. В этом случае я настоятельно рекомендую вам убедиться, что вы используете последнюю версию пакета и добавляете эту информацию (номер версии) в свой вопрос. – flodel

+0

'x [as.logical (! A <0)]', кажется, удаляет значения NA ... – agstudy

ответ

3

Как @flodel указывает, вопрос может быть упрощена, почему это не TRUE:

identical(x[as.logical(a)], x[!!as.logical(a)]) # note the double bangs 

Ответ заключается в том, как data.table ручки NA в i и как она обрабатывает в i!. Оба из них получают специальное лечение. Проблема действительно возникает в сочетании двух.

  • NA «s в i рассматриваются как FALSE.
  • ! в i рассматриваются как отрицание.

Это хорошо описано в ?.data.table (как указывает Г. Гротендик в другом ответе). Соответствующие части:

Целые и логические векторы работают так же, как в [.data.frame. Помимо NA в логическом i, они рассматриваются как FALSE, и один логический элемент NA не перерабатывается, чтобы соответствовать количеству строк, так как он находится в [.data.frame.
...
Все типы «i» могут иметь префикс!. Это означает, что необходимо выполнить не-join или not-select. Во всей документации data.table, где мы говорим о типе «i», мы подразумеваем тип «i» после «!», Если он присутствует.

Если вы посмотрите на код [.data.table, как ! обрабатываются, если присутствует, является

  1. удаления предшествующую !
  2. Устный оставшиеся i
  3. Отрицание, что интерпретация

Путь NA s обрабатываются путем установки этих значений на FALSE.
Однако - и очень важно - это происходит в шаге 2 выше.

Таким образом, то, что происходит на самом деле в том, что когда i содержит NA И i предваряется !, то NA являются эффективно интерпретировать как TRUE. Хотя это технически, это задокументировано, я не уверен, что это так, как предполагалось.


Конечно, есть последний вопрос точки @ flodel: почему это x[as.logical(a)] не то же самое, как x[!!as.logical(a)]?Причиной этого является то, что только первый bang получает специальную обработку. Второй взлом интерпретируется как нормальный на R.

С !NA еще NA, последовательность изменений для интерпретации !! (NA) является:

!!(NA) 
!(!(NA)) 
!( NA ) 
!(FALSE) 
TRUE 
1

Это документированное поведение. См. Описание аргумента i в ?data.table.

+1

Gabor, я бы сказал, что то, что документировано, может немного отличаться от того, что мы здесь видим. В частности, я думаю, комментарий @ flodel очень уместен. Скорее, «NA интерпретируется как FALSE» должно появиться после '!'. т.е., что '! NA' следует рассматривать так же, как' NA' –

+0

Согласовано. Бросить «NA» или нет - это документированный выбор дизайна. '[.data.frame' сохраняет их, в то время как' .data.table' и 'subset' не работают. В этом нет ничего плохого. Проблема в том, что 'data.table', похоже, имеет серьезную проблему, обеспечивающую согласование логических правил. Я нахожу нормальным/интуитивным, что 'subset (x, as.logical (a))' и 'subset (x, !! as.logical (a))' возвращает тот же результат. Однако в случае '.data.table',' x [as.logical (a)] и 'x [!! as.logical (a)]' do not ... – flodel

+0

Также запрос функции и последний абзац ответа @ MatthewDowle здесь: http://stackoverflow.com/questions/16221742/subsetting-a-data-table-using-some-non-na-excludes-na-too/17008872#17008872 сделать меня действительно неудобным. Большинство из них, похоже, полагаются на неправильную (или новую?) Концепцию, что '! NA' должно быть« TRUE ». – flodel