J'utilise data.table et il existe de nombreuses fonctions qui m'obligent à définir une clé (par exemple X[Y]
). En tant que tel, je souhaite comprendre ce que fait une clé afin de définir correctement les clés dans mes tables de données.
Une source que j'ai lue était ?setkey
.
setkey()
trie undata.table
et le marque comme trié. Les colonnes triées sont la clé. La clé peut être n'importe quelle colonne dans n'importe quel ordre. Les colonnes sont toujours triées par ordre croissant. Le tableau est modifié par référence. Aucune copie n'est effectuée, à l'exception de la mémoire de travail temporaire de la taille d'une colonne.
Ce que je retiens ici, c'est qu'une clé «trierait» la table data.table, ce qui aurait un effet très similaire à order()
. Cependant, cela n'explique pas le but d'avoir une clé.
La FAQ data.table 3.2 et 3.3 explique:
3.2 Je n'ai pas de clé sur une grande table, mais le regroupement est toujours très rapide. Pourquoi donc?
data.table utilise le tri par base. C'est beaucoup plus rapide que les autres algorithmes de tri. Radix est uniquement pour les entiers, voir
?base::sort.list(x,method="radix")
. C'est aussi une des raisons pour lesquellessetkey()
c'est rapide. Lorsqu'aucune clé n'est définie, ou que nous groupons dans un ordre différent de celui de la clé, nous l'appelons un par ad hoc.3.3 Pourquoi le regroupement par colonnes dans la clé est-il plus rapide qu'un ad hoc par?
Parce que chaque groupe est contigu en RAM, minimisant ainsi les récupérations de pages, et la mémoire peut être copiée en masse (
memcpy
en C) plutôt qu'en boucle en C.
À partir de là, je suppose que la définition d'une clé permet en quelque sorte à R d'utiliser le "tri par base" sur d'autres algorithmes, et c'est pourquoi il est plus rapide.
Le guide de démarrage rapide de 10 minutes contient également un guide sur les clés.
- Clés
Commençons par considérer data.frame, spécifiquement les noms de lignes (ou en anglais, les noms de lignes). Autrement dit, les noms multiples appartenant à une seule ligne. Les noms multiples appartenant à la seule ligne? Ce n'est pas ce à quoi nous sommes habitués dans un data.frame. Nous savons que chaque ligne a au plus un nom. Une personne a au moins deux noms, un premier nom et un deuxième nom. Cela est utile pour organiser un annuaire téléphonique, par exemple, qui est trié par nom, puis par premier nom. Cependant, chaque ligne d'un data.frame ne peut avoir qu'un seul nom.
Une clé se compose d'une ou plusieurs colonnes de noms de lignes, qui peuvent être des nombres entiers, des facteurs, des caractères ou une autre classe, pas simplement des caractères. De plus, les lignes sont triées par clé. Par conséquent, un data.table peut avoir au plus une clé, car il ne peut pas être trié de plusieurs manières.
L'unicité n'est pas appliquée, c'est-à-dire que les valeurs de clé en double sont autorisées. Puisque les lignes sont triées par clé, tous les doublons dans la clé apparaîtront consécutivement
L'annuaire téléphonique a été utile pour comprendre ce qu'est une clé, mais il semble qu'une clé ne soit pas différente par rapport à une colonne de facteurs. De plus, il n'explique pas pourquoi une clé est nécessaire (notamment pour utiliser certaines fonctions) et comment choisir la colonne à définir comme clé. De plus, il semble que dans une data.table avec le temps comme colonne, définir une autre colonne comme clé gâcherait probablement la colonne de temps aussi, ce qui la rend encore plus déroutante car je ne sais pas si je suis autorisé à définir une autre colonne comme clé. Quelqu'un peut-il m'éclairer s'il vous plaît?