Почему data.table определен: = а не перегрузка <-?
data.table ввел оператор: =. Почему бы не перегрузить < -?
Ответы
Ответ 1
Я не думаю, что есть какая-то техническая причина, по которой это необходимо, по следующей причине: :=
используется только внутри [...]
, поэтому он всегда цитируется. [...]
проходит через дерево выражений, чтобы увидеть, есть ли в нем :=
.
Это означает, что он не действует как оператор и не перегружен; поэтому они могли бы выбрать практически любого оператора, которого они хотели. Думаю, может быть, это выглядело лучше? Или менее запутанным, потому что это явно не <-
?
(Обратите внимание, что если :=
использовалось вне [...]
, это не могло быть <-
, потому что вы не можете перегрузить <-
. <-
Не оценивает его аргумент lefthand, t знать, что такое тип).
Ответ 2
Есть два места, которые <-
могут быть "перегружены":
x[i, j] <- value # 1
x[i, {colname <- value}] # 2
Первая копирует все x
в *tmp*
, меняет рабочую копию и возвращает x
. Это вещь R (src/main/eval.c и subassign.c) обсуждалась недавно на r-devel здесь. Казалось, что возможно изменить R, чтобы позволить пакетам или самому R избежать этой копии до *tmp*
, но в настоящее время это невозможно, IIUC.
Во-вторых, это то, о чем говорит Оуэн. Если вы согласны с тем, что это нормально для выполнения задания по ссылке в j
, как это, то какой оператор? Согласно комментарию к ответу Оуэна, <-
и <<-
уже используются пользователями в j
, поэтому мы нажимаем :=
.
Даже если [<-
не скопировал все x
, нам все равно нравится :=
в j
, поэтому мы можем делать такие вещи:
DT[,{newcol1:=sum(a)
newcol2:=a/newcol1}, by=group]
Если новые столбцы добавляются посредством ссылки на таблицу, а RHS каждого :=
оценивается внутри каждой группы. (Когда: = внутри группы реализовано.)
Обновление Oct 2012
Начиная с 1.8.2 (по CRAN в июле 2012 года), :=
по группе была реализована для добавления или обновления отдельных столбцов; то есть одиночный LHS :=
. И теперь в v1.8.3 (по R-Forge на момент написания) несколько столбцов могут быть добавлены группой; например.
DT[, c("newcol1","newcol2") := .(sum(a),sum(b)), by=group]
или, возможно, более элегантно:
DT[,`:=`(newcol1=sum(a),
newcol2=sum(b)), by=group]
Но итеративный множественный RHS, предполагаемый на некоторое время, где второе выражение может использовать результат из первого, еще не реализовано (FR # 1492). Таким образом, это все равно приведет к ошибке "newcol1 not found"
и должно быть выполнено в два этапа:
DT[,`:=`(newcol1=sum(a),
newcol2=a/newcol1), by=group]