Приходится дважды вызывать переменную перед оценкой?

Здесь происходит что-то действительно странное. В приведенном ниже коде я создаю переменную с именем temp. Я должен вызвать его дважды, прежде чем я смогу увидеть, что это такое. Например. При первом вызове консоль ничего не показывает. Во второй раз он показывает data.table/data.frame, что это такое. Может ли кто-нибудь помочь мне понять, что здесь происходит?

library(magrittr)
library(data.table)

myDT <- as.data.table(mtcars)


temp <- 
    myDT %>%
    melt(id.vars = c('cyl', 'mpg', 'hp'), 
         measure.vars = c('vs','am','gear','carb'),
         variable.name = 'Data') %>%
    extract( value > 0) %>%
    extract( , value := NULL)

Что делает моя консоль (первый вызов ничего не делает):

> temp
> temp
    cyl  mpg  hp Data
 1:   4 22.8  93   vs
 2:   6 21.4 110   vs
 3:   6 18.1 105   vs
 4:   4 24.4  62   vs
 5:   4 22.8  95   vs
 ...
 ...

person jks612    schedule 08.01.2016    source источник
comment
Я также вижу это в RStudio и Rterm (версия R 3.2.2 (2015-08-14); платформа: x86_64-w64-mingw32/x64 (64-разрядная); data.table_1.9.6). print.data.frame(temp) работает с первого раза.   -  person jbaums    schedule 08.01.2016
comment
Я всегда замечал это после := или set() звонка в data.table   -  person tospig    schedule 08.01.2016
comment
Я уверен, что видел это раньше как известное поведение с data.table. Где-то на SO есть дубликат, возможно, один из гуру data.table знает, где он.   -  person joran    schedule 08.01.2016
comment


Ответы (1)


Это известный побочный эффект исправления, реализованного для устранения еще большей ошибки. Он задокументирован здесь, как первый пункт в разделе "ИСПРАВЛЕНИЯ ОШИБОК" выпуска v1.9.6. Цитата из той ссылки:

если (ИСТИНА) DT[,LHS:=RHS] больше не печатает, #869 и #1122. Добавлены тесты. Чтобы заставить это работать, нам пришлось смириться с одним недостатком: если := используется внутри функции без DT[] до конца функции, то в следующий раз, когда DT или print(DT) будут напечатаны в конце подсказка, ничего не будет напечатано. Будет напечатано повторное DT или print(DT). Чтобы избежать этого: включите DT[] после последнего := в вашу функцию. Если это невозможно (например, это не функция, которую вы можете изменить), то DT[] в приглашении гарантированно будет напечатан. Как и прежде, добавление дополнительного [] в конце запроса := является рекомендуемой идиомой для обновления и последующей печати; например > DT[,foo:=3L][]. Спасибо Jureiss и Jan Gorecki за репортаж.

Как объяснено там, решение состоит в том, чтобы добавить завершающий [] к последней операции, содержащей :=, в вашей функции. Здесь это будет означать следующее:

library(magrittr)
library(data.table)    
myDT <- as.data.table(mtcars)
temp <- 
    myDT %>%
    melt(id.vars = c('cyl', 'mpg', 'hp'), 
         measure.vars = c('vs','am','gear','carb'),
         variable.name = 'Data') %>%
    extract( value > 0) %>%
    extract( , value := NULL) %>% `[`

## Following which, this will print the first time
temp
person Josh O'Brien    schedule 08.01.2016