tutorial - R data.table se rompe en funciones exportadas
data.table r (1)
El problema, como @GSee señaló (bajo comentarios) parece ser LINK todavía.
Para averiguar si un paquete es compatible con data.table , data.table
llama a la función cedta()
, que es:
> data.table:::cedta
function (n = 2L)
{
te = topenv(parent.frame(n))
if (!isNamespace(te))
return(TRUE)
nsname = getNamespaceName(te)
ans = nsname == "data.table" || "data.table" %chin% names(getNamespaceImports(te)) ||
"data.table" %chin% tryCatch(get(".Depends", paste("package",
nsname, sep = ":"), inherits = FALSE), error = function(e) NULL) ||
(nsname == "utils" && exists("debugger.look", parent.frame(n +
1L))) || nsname %chin% cedta.override || identical(TRUE,
tryCatch(get(".datatable.aware", asNamespace(nsname),
inherits = FALSE), error = function(e) NULL))
if (!ans && getOption("datatable.verbose"))
cat("cedta decided ''", nsname, "'' wasn''t data.table aware/n",
sep = "")
ans
}
<bytecode: 0x7ff67b9ca190>
<environment: namespace:data.table>
El cheque relevante aquí es:
"data.table" %chin% get(".Depends", paste("package", nsname, sep=":"), inherits=FALSE)
Cuando un paquete depende de data.table
, el comando anterior debe devolver TRUE
, es decir, si instaló el paquete a través de R CMD INSTALL
y luego cargó el paquete. Esto se debe a que, cuando carga el paquete, R crea de forma predeterminada una variable ".Depends" en el espacio de nombres. Si lo hiciste:
ls("package:test", all=TRUE)
# [1] ".Depends" "foo"
Sin embargo, cuando haces devtools:::load_all()
, esta variable no parece estar configurada.
# new session + set path to package''s dir
devtools:::load_all()
ls("package:test", all=TRUE)
# [1] "foo"
Entonces, cedta()
no llega a saber que este paquete depende de data.table
. Sin embargo, cuando establece manualmente .datatable.aware=TRUE
, la línea:
identical(TRUE, get(".datatable.aware", asNamespace(nsname), inherits = FALSE))
se ejecuta, lo que devolverá TRUE y por lo tanto supera el problema. Pero el hecho de que devtools
no coloque la variable .Depends
en el espacio de nombres del paquete sigue ahí.
Con todo, esto realmente no es un problema con data.table
.
Tengo problemas para que data.table funcione en las funciones exportadas de roxygen2.
Aquí hay una función simple y falsa en un archivo llamado foo.R (ubicado en el directorio R de mi paquete) que usa data.table:
#'' Data.table test function
#'' @export
foo <- function() {
m <- data.table(c1 = c(1,2,3))
print(is.data.table(m))
m[,sum(c1)]
}
Si copio y pego esta función en R, esta función funciona bien:
> foo <- function() {
+ m <- data.table(c1 = c(1,2,3))
+ print(is.data.table(m))
+ m[,sum(c1)]
+ }
> foo()
[1] TRUE
[1] 6
Pero si simplemente cargo la función exportada, R piensa que data.table es un data.frame y se rompe:
> rm(foo)
> load_all()
Loading test_package
> foo
function() {
m <- data.table(c1 = c(1,2,3))
print(is.data.table(m))
m[,sum(c1)]
}
<environment: namespace:test_package>
> foo()
[1] TRUE
Error in `[.data.frame`(x, i, j) : object ''c1'' not found
¿Que pasa?
ACTUALIZAR
Gracias a @GSee por la ayuda. Parece que esto es en realidad un problema de devtools. Echa un vistazo al código de línea de comando interactivo a continuación.
Después de cargar la biblioteca test_package, foo
ejecuta correctamente:
> foo
function ()
{
m <- data.table(c1 = c(1, 2, 3))
print(is.data.table(m))
m[, sum(c1)]
}
<environment: namespace:test_package>
> foo()
[1] TRUE
[1] 6
Al ejecutar load_all()
rompe foo:
> load_all()
Loading test_package
> foo()
[1] TRUE
Error in `[.data.frame`(x, i, j) : object ''c1'' not found
De alguna manera la source(''R/foo.R'')
revive la funcionalidad de foo:
> source(''R/foo.R'')
> foo
function() {
m <- data.table(c1 = c(1,2,3))
print(is.data.table(m))
m[,sum(c1)]
}
> foo()
[1] TRUE
[1] 6
Y las llamadas futuras a load_all()
no vuelven a romper foo
:
> load_all()
Loading test_package
> foo
function() {
m <- data.table(c1 = c(1,2,3))
print(is.data.table(m))
m[,sum(c1)]
}
> foo()
[1] TRUE
[1] 6
Además, actualicé a devtools 1.5 y traté de agregar .datatable.aware=TRUE
, pero eso no pareció hacer nada.