with tutorial style studio sheet examples espaƱol ejemplos div cheat apps r data.table

tutorial - tags$div shiny



AsignaciĆ³n por referencia en conjuntos de datos de paquetes cargados (2)

Esto no tiene nada que ver con los conjuntos de datos o el bloqueo, puede reproducirlo simplemente usando

DT<-unserialize(serialize(data.table(b = 1:5),NULL)) foo(DT) DT

Sospecho que tiene que ver con el hecho de que data.table tiene que volver a crear el extptr dentro del objeto en el primer acceso en DT , pero lo está haciendo en una copia, por lo que no hay forma de que pueda compartir la modificación con el original. en el entorno global.

[De Mateo] Exactamente.

DT<-unserialize(serialize(data.table(b = 1:3),NULL)) DT b 1: 1 2: 2 3: 3 DT[,newcol:=42] DT # Ok. DT rebound to new shallow copy (when direct) b newcol 1: 1 42 2: 2 42 3: 3 42 DT<-unserialize(serialize(data.table(b = 1:3),NULL)) foo(DT) b a 1: 1 1 2: 2 1 3: 3 1 DT # but not ok when via function foo() b 1: 1 2: 2 3: 3


DT<-unserialize(serialize(data.table(b = 1:3),NULL)) alloc.col(DT) # alloc.col needed first b 1: 1 2: 2 3: 3 foo(DT) b a 1: 1 1 2: 2 1 3: 3 1 DT # now it''s ok b a 1: 1 1 2: 2 1 3: 3 1

O, no pase DT a la función, solo refiérase a ella directamente. Use data.table como una base de datos: algunas tablas de nombres fijos en .GlobalEnv .

DT <- unserialize(serialize(data.table(b = 1:5),NULL)) foo <- function() { DT[, newcol := 7] } foo() b newcol 1: 1 7 2: 2 7 3: 3 7 4: 4 7 5: 5 7 DT # Unserialized data.table now over-allocated and updated ok. b newcol 1: 1 7 2: 2 7 3: 3 7 4: 4 7 5: 5 7

Estoy en el proceso de crear un paquete que utiliza una data.table datos como un conjunto de datos y tiene un par de funciones que se asignan por referencia usando := .

He construido un paquete simple para demostrar mi problem

library(devtools) install_github(''foo'',''mnel'')

Contiene dos funciones

foo <- function(x){ x[, a := 1] } fooCall <- function(x){ eval(substitute(x[, a :=1]),parent.frame(1)) }

y un conjunto de datos (no cargado perezoso) DT , creado usando

DT <- data.table(b = 1:5) save(DT, file = ''data/DT.rda'')

Cuando instalo este paquete, entiendo que foo(DT) debe asignar por referencia dentro de DT .

library(foo) data(DT) foo(DT) b a 1: 1 1 2: 2 1 3: 3 1 4: 4 1 5: 5 1 # However this has not assigned by reference within `DT` DT b 1: 1 2: 2 3: 3 4: 4 5: 5

Si uso lo mas correct

tracmem(DT) DT <- foo(DT) # This works without copying DT b a 1: 1 1 2: 2 1 3: 3 1 4: 4 1 5: 5 1 untracemem(DT)

Si utilizo eval y substitute dentro de la función.

fooCall(DT) b a 1: 1 1 2: 2 1 3: 3 1 4: 4 1 5: 5 1 # it does assign by reference DT b a 1: 1 1 2: 2 1 3: 3 1 4: 4 1 5: 5 1

Debería seguir con

  1. DT <- foo(DT) o la ruta eval / substitute , o
  2. ¿Hay algo que no entiendo sobre cómo los data cargan los conjuntos de datos, incluso cuando no son perezosos?

Otra solución es usar inst/extdata para guardar el archivo rda (que contendría cualquier número de objetos data.table) y tener un archivo DT.r dentro del subdirectorio de data

# get the environment from the call to `data()` env <- get(''envir'', parent.frame(1)) # load the data load(system.file(''extdata'',''DT.rda'', package= ''foo''), envir = env) # overallocate (evaluating in correct environment) if(require(data.table)){ # the contents of `DT.rda` are known, so write out in full evalq(alloc.col(DT), envir = env) } # clean up so `env` object not present in env environment after calling `data(DT)` rm(list = c(''env''), envir = env) }