studio - key data table r
¿Por qué data.table definido:=en lugar de sobrecargar<-? (2)
Hay dos lugares que <-
podrían estar ''sobrecargados'':
x[i, j] <- value # 1
x[i, {colname <- value}] # 2
La primera copia la totalidad de x
a *tmp*
, cambia esa copia de trabajo y asigna de nuevo a x
. Eso es una cosa R (src / main / eval.c y subassign.c) discutida recientemente en r-devel here . Parecía que podría ser posible cambiar R para permitir que los paquetes, o R en sí, eviten 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 dentro de j
así, ¿qué operador? De acuerdo con el comentario a la respuesta de Owen, los usuarios de j
ya usan <-
y <<-
, así que encontramos :=
.
Incluso si [<-
no copiamos 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 se agregan las nuevas columnas por referencia a la tabla, y se evalúa el RHS de cada :=
dentro de cada grupo. (Cuando: = dentro del grupo se implementa.)
Actualización oct 2012
A partir de 1.8.2 (en CRAN en julio de 2012), se implementó :=
por grupo para agregar o actualizar columnas individuales; es decir, solo LHS de :=
. Y ahora en v1.8.3 (en R-Forge al momento de escribir), 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 de la primera, aún no está implementado ( FR#1492 ). Por lo tanto, esto aún dará un error "newcol1 not found"
y debe hacerse en dos pasos:
DT[,`:=`(newcol1=sum(a),
newcol2=a/newcol1), by=group]
data.table ha introducido el operador: =. ¿Por qué no sobrecargar <-?
No creo que exista ninguna razón técnica por la que sea necesario, por la siguiente razón :=
solo se utiliza en el interior, [...]
por lo que siempre se cita. [...]
recorre el árbol de expresiones para ver si :=
está en él.
Eso significa que realmente no actúa como un operador y no está realmente sobrecargado; por lo que podrían haber elegido casi 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 usó fuera de [...]
él no podría ser <-
, porque realmente no puede sobrecargar <-
. <-
No evalúa su argumento de izquierda, por lo que no sabe cuál es el tipo es).