Buscar..


Introducción

La clave y los índices de una tabla de datos permiten que ciertos cálculos se ejecuten más rápido, principalmente relacionados con uniones y subconjuntos. La clave describe el orden de clasificación actual de la tabla; mientras que cada índice almacena información sobre el orden de la tabla con respecto a una secuencia de columnas. Consulte la sección "Comentarios" a continuación para obtener enlaces a las viñetas oficiales sobre el tema.

Observaciones

Las viñetas oficiales son la mejor introducción a este tema:

Teclas vs índices

Una tabla de datos puede ser "codificada" por una secuencia de columnas, indicando a las funciones interesadas que los datos están ordenados por esas columnas. Para obtener o configurar la clave, use las funciones documentadas en ?key .

De manera similar, las funciones pueden aprovechar los "índices" de una tabla de datos. Cada índice, y una tabla puede tener más de uno, almacena información sobre el orden de los datos con respecto a una secuencia de columnas. Al igual que una clave, un índice puede acelerar ciertas tareas. Para obtener o establecer índices, utilice las funciones documentadas en los ?indices

Los índices también se pueden configurar automáticamente (actualmente solo para una columna a la vez). Consulte ?datatable.optimize para obtener detalles sobre cómo funciona esto y cómo desactivarlo si es necesario.

Verificación y actualización.

Los valores que faltan se permiten en una columna de clave.

Las claves y los índices se almacenan como atributos y pueden, por accidente, no corresponder al orden real de los datos en la tabla. Muchas funciones verifican la validez de la clave o el índice antes de usarla, pero vale la pena tenerlas en cuenta.

Las claves y los índices se eliminan después de las actualizaciones donde no es obvio que se conserva el orden de clasificación. Por ejemplo, a partir de DT = data.table(a=c(1,2,4), key="a") , si actualizamos como DT[2, a := 3] , la clave está rota.

Mejora del rendimiento para seleccionar subconjuntos

# example data
set.seed(1)
n  = 1e7
ng = 1e4
DT = data.table(
    g1  = sample(ng, n, replace=TRUE),
    g2  = sample(ng, n, replace=TRUE),
    v  = rnorm(n)
)

Coincidencia en una columna

Después de la primera ejecución de una operación de subconjunto con == o %in% ...

system.time(
    DT[ g1 %in% 1:100]
)
#    user  system elapsed 
#    0.12    0.03    0.16 

Se ha creado automáticamente un índice para g1 . Las siguientes operaciones de subconjunto se ejecutan casi instantáneamente:

system.time(
    DT[ g1 %in% 1:100]
)
#    user  system elapsed 
#       0       0       0

Para controlar cuándo se crea o utiliza un índice, agregue la opción verbose=TRUE o cambie las options(datatable.verbose=TRUE) configuración global options(datatable.verbose=TRUE) .

Coincidencia en múltiples columnas

Actualmente, la coincidencia en dos columnas no crea automáticamente un índice:

system.time(
    DT[ g1 %in% 1:100 & g2 %in% 1:100]
)
#    user  system elapsed 
#    0.57    0.00    0.57

Vuelva a ejecutar esto y seguirá siendo lento. Incluso si agregamos manualmente el índice con setindex(DT, g1, g2) , seguirá siendo lento porque esta consulta aún no está optimizada por el paquete.

Afortunadamente, si podemos enumerar las combinaciones de valores que queremos buscar y hay un índice disponible, podemos unirnos rápidamente:

system.time(
    DT[ CJ(g1 = 1:100, g2 = 1:100, unique=TRUE), on=.(g1, g2), nomatch=0]
)
#    user  system elapsed 
#    0.53    0.00    0.54 
setindex(DT, g1, g2)
system.time(
    DT[ CJ(g1 = 1:100, g2 = 1:100, unique=TRUE), on=.(g1, g2), nomatch=0]
)
#    user  system elapsed 
#       0       0       0

Con CJ , es importante tener cuidado con la cantidad de combinaciones que se vuelven demasiado grandes.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow