разные результаты для стандартной формы и функциональной формы data.table, присваиваемой по ссылке `: =`

Кажется, есть небольшая разница между назначением data.tabel по ссылке: = в стандарте функциональной форме.

Стандартная форма приводит RHS к вектору, а функциональная - нет. Деталь, но не задокументированная, как я полагаю.

library(data.table)
dt <- data.table(a = c('a','b','c'))
v <- c('A','B','C')
l <- list(v)

all.equal(copy(dt)[, new := v], copy(dt)[, `:=` (new = v)])
# [1] TRUE
all.equal(copy(dt)[, new := l], copy(dt)[, `:=` (new = l)])
# [1] "Datasets have different column modes. First 3: new(character!=list)"

copy(dt)[, new := l][]
#    a new
# 1: a   A
# 2: b   B
# 3: c   C

copy(dt)[, `:=` (new = l)][]
#    a   new
# 1: a A,B,C
# 2: b A,B,C
# 3: c A,B,C

Это основное изменение того, как я изначально задавал этот вопрос.


person rluech    schedule 19.05.2017    source источник
comment
Fwiw, вы должны использовать X[Y, on=, col], а не X[Y, on=][, col], поскольку последний создает объединение для всех столбцов перед выбором одного необходимого столбца.   -  person Frank    schedule 19.05.2017
comment
Безусловно, спасибо за подсказку. Присоединиться к унаследованной области. Я отредактировал вопрос, чтобы прояснить проблему.   -  person rluech    schedule 24.05.2017
comment
Я думаю, это происходит потому, что RHS всегда должен быть списком векторов столбцов, но в LHS := RHS для удобства можно писать его без list. В документе говорится, что до тех пор, пока j возвращает список, каждый элемент списка становится столбцом в итоговой таблице data.table. Это расширенный режим по умолчанию. ... но я не уверен, что здесь имеется в виду под расширенным режимом.   -  person Frank    schedule 24.05.2017


Ответы (1)


Это очень хороший вопрос, который касается дизайнерского решения об операторе :=.

Для простых вызовов с использованием := в качестве оператора, например col := val, мы решили автоматически поместить val в список. Это решение было принято, чтобы пользователям было удобнее назначать один столбец.

Когда вы используете форму вызова функции, ":="(col = val) мы больше не помещаем val в список. Это уже расширенная форма. := действует как псевдоним для list, но обновляется на месте. Вы всегда можете проверить, какой будет обновленный столбец, изменив := на list (или .), например .(col = val).

Не то чтобы даже при использовании := в качестве оператора вам все равно нужно было указать RHS в качестве списка, в котором вы создаете 2+ столбца, c("col1","col2") := list(val1, val2).

person jangorecki    schedule 21.02.2019