Recherche…


Introduction

La clé et les index d'un data.table permettent à certains calculs de s'exécuter plus rapidement, principalement liés aux jointures et aux sous-ensembles. La clé décrit l'ordre de tri actuel de la table; tandis que chaque index stocke des informations sur l'ordre de la table en respectant une séquence de colonnes. Voir la section «Remarques» ci-dessous pour des liens vers les vignettes officielles sur le sujet.

Remarques

Les vignettes officielles sont la meilleure introduction à ce sujet:

Clés vs indices

Une data.table peut être "saisie" par une séquence de colonnes, indiquant aux fonctions intéressées que les données sont triées par ces colonnes. Pour obtenir ou définir la clé, utilisez les fonctions documentées à la ?key

De même, les fonctions peuvent tirer parti des "indices" de data.table. Chaque index - et une table peut en avoir plusieurs - stocke des informations sur l’ordre des données en respectant une séquence de colonnes. Comme une clé, un index peut accélérer certaines tâches. Pour obtenir ou définir des indices, utilisez les fonctions documentées dans ?indices .

Les indices peuvent également être définis automatiquement (actuellement pour une seule colonne à la fois). Voir ?datatable.optimize pour plus de détails sur son fonctionnement et sa désactivation si nécessaire.

Vérification et mise à jour

Les valeurs manquantes sont autorisées dans une colonne de clé.

Les clés et les index sont stockés en tant qu'attributs et peuvent, par accident, ne pas correspondre à l'ordre réel des données dans la table. De nombreuses fonctions vérifient la validité de la clé ou de l'index avant de l'utiliser, mais il convient de garder à l'esprit.

Les clés et les index sont supprimés après les mises à jour, où il n'est pas évident que l'ordre de tri est préservé. Par exemple, à partir de DT = data.table(a=c(1,2,4), key="a") , si nous mettons à jour comme DT[2, a := 3] , la clé est brisée.

Amélioration des performances pour la sélection des sous-ensembles

# 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)
)

Correspondance sur une colonne

Après la première exécution d'une opération de sous-ensemble avec == ou %in% ...

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

Un index a été créé automatiquement pour g1 . Les opérations subséquentes de sous-ensembles s'exécutent presque instantanément:

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

Pour surveiller la création ou l'utilisation d'un index, ajoutez l'option verbose=TRUE ou modifiez les options(datatable.verbose=TRUE) paramètres globaux options(datatable.verbose=TRUE) .

Correspondance sur plusieurs colonnes

Actuellement, la correspondance sur deux colonnes ne crée pas automatiquement un index:

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

Relancez ceci et il restera lent. Même si nous ajoutons manuellement l'index avec setindex(DT, g1, g2) , il restera lent car cette requête n'est pas encore optimisée par le package.

Heureusement, si nous pouvons énumérer les combinaisons de valeurs que nous souhaitons rechercher et qu’un index est disponible, nous pouvons rapidement les joindre:

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

Avec CJ , il est important de faire attention au nombre de combinaisons devenant trop important.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow