style - r datatable extension
Knitr es engaƱado por data.table `:=` asignaciĆ³n (5)
¿Por qué no solo usar:
```{r, results=''hide''}
DT[, c:=5]
```
Parece que knitr
no entiende que DT[, a:=1]
no debería dar como resultado una salida de DT
al documento. ¿Hay alguna manera de detener este comportamiento?
Ejemplo de documento knitr
:
Data.Table Markdown
========================================================
Suppose we make a `data.table` in **R Markdown**
```{r}
DT = data.table(a = rnorm(10))
```
Notice that it doesn''t display the contents until we do a
```{r}
DT
```
style command. However, if we want to use `:=` to create another column
```{r}
DT[, c:=5]
```
It would appear that the absence of a equals sign tricks `knitr` into thinking this
is to be printed.
Salida Knitr:
¿Es esto un error knitr
o un error data.table
?
EDITAR
Acabo de knitr
cuenta de que knitr
está siendo extraño cuando hace echo
del código. Mira el resultado de arriba. En mi código fuente tengo DT[, c:=5]
pero lo que knitr
representa es
DT[, `:=`(c, 5)]
Extraño...
EDIT 2: almacenamiento en caché
El almacenamiento en caché también parece tener un problema con :=
pero esa debe ser una causa diferente, por lo que aquí hay una pregunta diferente: ¿por qué el almacenamiento en caché knitr falla para data.table `: =`?
Me encontré con el mismo problema y lo resolví con bastante facilidad reasignando la variable. En tu caso:
DT <- DT[, '':='' (c, 5)]
Aunque es un poco más detallado, especialmente si el nombre de la variable es grande.
Para cualquiera que regrese a esto en 2017 con RMarkdown 1.3 y data.table 1.10 o similar, hubo un resurgimiento de este error, como se identificó y documentó aquí.
Esto se corrigió posteriormente en RMarkdown 1.4
Simplemente rodea la expresión con invisible (). Esto funciona para mí
Actualización de octubre de 2014 . Ahora en data.table v1.9.5:
:=
ya no se imprime enknitr
para coherencia con el comportamiento en el prompt, #505 . La salida de unknit("knitr.Rmd")
pruebaknit("knitr.Rmd")
ahora se encuentra en las pruebas unitarias de data.table.
y relacionado :
if (TRUE) DT[,LHS:=RHS]
ahora no se imprime (gracias a Jureiss, #869 ). Prueba agregada Para que esto funcione, hemos tenido que vivir con un inconveniente: si a:=
se usa dentro de una función sinDT[]
antes del final de la función, entonces la próxima vez que se escribaDT
en el aviso, nada será impreso. Se imprimirá unDT
repetido. Para evitar esto: incluya unDT[]
después del último:=
en su función. Si eso no es posible (p. Ej., No se trata de una función que pueda cambiar), se garantiza que seprint(DT)
yDT[]
cuando se solicite. Como antes, agregar un[]
adicional al final de una consulta:=
es una expresión recomendada para actualizar y luego imprimir; eg> DT[,foo:=3L][]
Se mantuvo la respuesta anterior para la posteridad (el negocio global$depthtrigger
ya no se realiza a partir de data.table v1.9.5, por lo que ya no es cierto) ...
Para que quede claro, lo entiendo: knitr
está imprimiendo cuando no lo desea.
Intente aumentar un poco data.table:::.global$depthtrigger
al comienzo del script.
Esto será 3 para ti actualmente:
data.table:::.global$depthtrigger
[1] 3
No sé cuánta profundidad eval knitr
agrega a la pila. Pero intente cambiar el gatillo a 4 primero; es decir
assign("depthtrigger", 4, data.table:::.global)
y al final del script knitr
asegúrate de volver a establecerlo en 3. Si 4 no funciona, prueba 5, luego 6. Si llegas a 10, te rindes y lo pensaré de nuevo. ;-PAG
¿Por qué podría esto funcionar?
Ver NOTICIAS de v1.8.4:
DT[,LHS:=RHS,...]
ya no imprimeDT
. Esto implementa # 2128 "Intenta de nuevo obtenerDT[i,j:=value]
para que vuelva de forma invisible". Gracias a las discusiones aquí:
cómo suprimir la salida cuando se utiliza `: =` en R {data.table}, antes de v1.8.3?
http://r.789695.n4.nabble.com/Avoiding-print-when-using-tp4643076.html
Las preguntas frecuentes 2.21 y 2.22 han sido actualizadas.FAQ 2.21 ¿Por qué DT [i, col: = value] devuelve la totalidad de DT? No esperaba ningún valor visible (consistente con <-), o un mensaje o valor de retorno que contenía cuántas filas se actualizaron. No es obvio que los datos se hayan actualizado por referencia.
Esto ha cambiado en v1.8.3 para cumplir con sus expectativas. Por favor actualice Se devuelve todo DT (ahora de forma invisible) para que la sintaxis compuesta pueda funcionar; por ejemplo, DT [i, hecho: = VERDADERO] [, suma (hecho)]. El número de filas actualizadas se devuelve cuando la verbosidad está activada, ya sea por consulta o globalmente utilizando opciones (datatable.verbose = TRUE).Preguntas frecuentes 2.22 Ok, gracias. ¿Qué fue tan difícil sobre el resultado de DT [i, col: = value] que se devolvió de forma invisible?
R internamente fuerza la visibilidad para [. El valor de la columna de evaluación de FunTab (vea src / main / names.c) para [es 0 significa fuerza R_Visible en (vea R-Internals sección 1.6). Por lo tanto, cuando probamos invisible () o configuramos R_Visible en 0 directamente nosotros mismos, eval in src / main / eval.c lo volvería a forzar. Para resolver este problema, la clave era dejar de intentar detener el método de impresión ejecutándose después de a: =. En cambio, adentro: = ahora (desde v1.8.3) establecemos un indicador global que el método de impresión usa para saber si realmente se imprime o no.
Esa bandera global es data.table:::.global$print
. En la parte superior de data.table:::print.data.table
lo verá mirándolo. Esto se debe a que no existe una forma conocida de suprimir la impresión de [
(como lo explica la Pregunta frecuente 2.22).
Entonces, dentro de :=
dentro de [.data.table
, mira para ver qué tan "profunda" es esta llamada:
if (Cstack_info()[["eval_depth"]] <= .global$depthtrigger) {
suppPrint = function(x) { .global$print=FALSE; x }
# Suppress print when returns ok not on error, bug #2376.
# Thanks to: https://.com/a/13606880/403310
# All appropriate returns following this point are
# wrapped i.e. return(suppPrint(x)).
}
Esencial eso solo dice: si DT[,x:=y]
está ejecutando en el prompt, entonces sé que REPL va a llamar al método de print
en mi resultado, más allá de mi control. Ok, entonces, dado que el método de print
se va a ejecutar, voy a suprimirlo dentro de ese método de print
estableciendo un indicador (ya que el método de print
que se ejecuta (es decir, print.data.table
) es algo que puedo controlar).
En el caso de knitr
simula el REPL de una manera inteligente. En realidad, no es un script, iiuc; de lo contrario, DT[,x:=y]
no se imprimiría de todos modos por ese motivo. Pero debido a que está simulando REPL a través de una eval
existe un nivel adicional de profundidad de eval
para el código ejecutado desde knitr
. O algo similar (no sé knitr
).
Es por eso que estoy pensando que aumentar el depthtrigger
podría hacer el truco.
Hacky / Crufty, estoy de acuerdo. Pero si funciona, y me dices qué valor funciona, puedo cambiar data.table
para que sea knitr
con knitr
y cambie el depthtrigger
automáticamente. O cualquier solución mejor es bienvenida.