2012-05-10 21 views
56

Estoy tratando de usar el paquete data.table dentro de mi propio paquete. MWE es el siguiente:Uso del paquete data.table dentro de mi propio paquete

Creo una función, test.fun, que simplemente crea un pequeño objeto data.table, y luego suma la agrupación de columnas "Val" por la columna "A". El código es

test.fun<-function() 
{ 
    library(data.table) 
    testdata<-data.table(A=rep(seq(1,5), 5), Val=rnorm(25)) 
    setkey(testdata, A) 
    res<-testdata[,{list(Ct=length(Val),Total=sum(Val),Avg=mean(Val))},"A"] 
    return(res) 
} 

Cuando creo esta función en una sesión de R regular, a continuación, ejecutar la función, funciona como se esperaba.

> res<-test.fun() 
data.table 1.8.0 For help type: help("data.table") 
> res 
    A Ct  Total  Avg 
[1,] 1 5 -0.5326444 -0.1065289 
[2,] 2 5 -4.0832062 -0.8166412 
[3,] 3 5 0.9458251 0.1891650 
[4,] 4 5 2.0474791 0.4094958 
[5,] 5 5 2.3609443 0.4721889 

Cuando puse esta función en un paquete, instale el paquete, cargar el paquete, y luego ejecutar la función, aparece un mensaje de error.

> library(testpackage) 
> res<-test.fun() 
data.table 1.8.0 For help type: help("data.table") 
Error in `[.data.frame`(x, i, j) : object 'Val' not found 

¿Alguien puede explicarme por qué sucede esto y qué puedo hacer para solucionarlo? Cualquier ayuda es muy apreciada.

+11

Supongo que no has declarado una dependencia. Debe eliminar 'library (data.table)' de su función y declarar 'depends: data.table' en su espacio de nombres y DESCRIPTION. – Andrie

Respuesta

67

Supongo que Andrie tiene razón, +1. Hay un FAQ en él (ver vignette("datatable-faq")), así como un nuevo vignette en la importación de data.table:

FAQ 6.9: He creado un paquete que depende de data.table. ¿Cómo puedo hacer para que mi paquete sea data.table-aware para que funcione la herencia de data.frame?

De cualquier i) incluyen data.table en el campo de su archivo de descripción Depends:, o ii) incluir data.table en el campo de su archivo de descripción Imports: Y import(data.table) en el archivo de espacio de nombres.

Además fondo ... en la parte superior de [.data.table (y otras funciones data.table), verá un interruptor dependiendo del resultado de una llamada a cedta(). Esto significa Calling Environment Data Table Aware. Escribir data.table:::cedta revela cómo se hace. Se basa en que el paquete de llamada tiene un espacio de nombre y ese espacio de nombres Importar o Depender en data.table. Esta es la forma en data.table se puede pasar a la no paquetes data.table-Aware (tales como funciones en base) y esos paquetes puede utilizar la sintaxis absolutamente estándar [.data.frame en el data.table, felizmente inconscientes de que el data.frameis() un data.table, también.

Esta es también la razón por la herencia data.table no solía ser compatible con paquetes namespaceless, y por qué a petición del usuario tuvimos que pedirles a los autores de dichos paquetes que agreguen un espacio de nombres a su paquete para ser compatibles. Afortunadamente, ahora que R añade un espacio de nombres por defecto para los paquetes que faltan uno (de v2.14.0), ese problema se ha ido:

CAMBIOS EN LA VERSIÓN R 2.14.0
* Todos los paquetes deben tener un espacio de nombres, y uno se crea en la instalación si no se proporciona en las fuentes.

+4

+1 Gran respuesta. – Andrie

+0

(Siento revivir esto, pero ...) Matthew, ¿puedes aclarar cómo funcionaría esto desde un punto de vista interactivo? Si mi paquete devuelve un 'data.table' a un usuario en una sesión interactiva, ¿se les requerirá que utilicen la semántica' data.table', o hay alguna manera en que yo pueda soportar la conocida sintaxis 'data.frame'? –

+1

@JeffAllen Esa es una nueva ... no estoy seguro. Si su paquete depende de data.table, eso hará que el usuario data.table tenga en cuenta. Tal vez Importar data.table no (y tal vez eso es lo que le gustaría). –

14

Aquí está la receta completa:

1) Añadir a data.tableImports en su archivo DESCRIPTION.

2) Agregue @import data.table a su archivo .R respectivo (es decir, el archivo .R que alberga su función que arroja el error Error in [.data.frame(x, i, j) : object 'Val' not found).

3) Escriba library(devtools) y configure su directorio de trabajo para que apunte al directorio principal de su paquete R.

4) Tipo document(). Esto asegurará que su archivo NAMESPACE incluya una línea import(data.table).

5) Type build()

6) Type install()

Para una buena introducción a lo build() y install() hacer, ver: http://kbroman.org/pkg_primer/.

Entonces, una vez que cierre su sesión de R y acceder próxima vez, puede saltar inmediatamente a la derecha con:

1) Tipo de library("my_R_package")

2) escriba el nombre de la función que está alojado en el. R archivo mencionado anteriormente.

3) ¡Disfrútalo! Ya no deberías recibir el temido Error in [.data.frame(x, i, j) : object 'Val' not found

+2

el comando '@import data.table' es particularmente útil – mbarete

Cuestiones relacionadas