data.table ha introducido el operador: =. ¿Por qué no sobrecargar <-?
No creo que haya ninguna razón técnica que deba ser necesaria, por el siguiente motivo :=
solo se usa dentro [...]
modo que siempre se cita. [...]
recorre el árbol de expresiones para ver si :=
está en él.
Eso significa que no está realmente actuando como un operador y no está realmente sobrecargado; por lo que podrían haber elegido prácticamente cualquier operador que quisieran. ¿Supongo que tal vez se veía mejor? ¿O menos confuso porque claramente no es <-
?
(Tenga en cuenta que si :=
se usaron fuera de [...]
no podría ser <-
, porque en realidad no se puede sobrecargar <-
. <-
No evalúa su argumento de la izquierda, por lo que no sabe de qué tipo es).
Hay dos lugares donde <-
podría estar 'sobrecargado':
x[i, j] <- value # 1 x[i, {colname <- value}] # 2
El primero copia el total de x
a *tmp*
, cambia esa copia de trabajo y lo asigna a x
. Eso es algo R (src / main / eval.c y subassign.c) discutido recientemente en r-devel aquí . Parecía que era posible cambiar R para permitir paquetes, o R mismo, para evitar esa copia a *tmp*
, pero actualmente no es posible, IIUC.
El segundo es a lo que se refiere la respuesta de Owen, creo. Si acepta que está bien hacer la asignación por referencia en j
esa manera, ¿a qué operador? Según el comentario a la respuesta de Owen, <-
y <<-
ya están siendo utilizados por los usuarios en j
, así que llegamos a :=
.
Incluso si [<-
no copió la totalidad de x
, todavía nos gusta :=
en j
para que podamos hacer cosas como esta:
DT[,{newcol1:=sum(a) newcol2:=a/newcol1}, by=group]
Donde las nuevas columnas se agregan por referencia a la tabla, y la RHS de cada :=
se evalúa dentro de cada grupo. (Cuando: = dentro del grupo está implementado)
Actualización Oct 2012
A partir de 1.8.2 (en CRAN en julio de 2012),: :=
por grupo se implementó para agregar o actualizar columnas individuales; es decir, solo LHS de :=
. Y ahora en v1.8.3 (en R-Forge en el momento de la escritura), se pueden agregar múltiples columnas por grupo; p.ej,
DT[, c("newcol1","newcol2") := .(sum(a),sum(b)), by=group]
o, quizás más elegantemente:
DT[,`:=`(newcol1=sum(a), newcol2=sum(b)), by=group]
Pero el RHS múltiple iterativo , previsto por un tiempo, donde la segunda expresión podría usar el resultado del primero, aún no está implementado ( FR # 1492 ). Por lo tanto, esto dará un error "newcol1 not found"
y debe hacerse en dos pasos:
DT[,`:=`(newcol1=sum(a), newcol2=a/newcol1), by=group]