Estou usando data.table e há muitas funções que exigem que eu defina uma chave (por exemplo X[Y]
). Como tal, desejo entender o que uma chave faz para definir as chaves corretamente em minhas tabelas de dados.
Uma fonte que li foi ?setkey
.
setkey()
classifica umdata.table
e o marca como classificado. As colunas classificadas são a chave. A chave pode ser qualquer coluna em qualquer ordem. As colunas são classificadas sempre em ordem crescente. A tabela é alterada por referência. Nenhuma cópia é feita, exceto a memória de trabalho temporária com o tamanho de uma coluna.
Minha lição aqui é que uma chave "classificaria" a tabela de dados, resultando em um efeito muito semelhante a order()
. No entanto, não explica o propósito de ter uma chave.
As FAQ 3.2 e 3.3 da data.table explicam:
3.2 Não tenho uma chave em uma mesa grande, mas o agrupamento ainda é muito rápido. Por que é que?
data.table usa classificação raiz. Isso é significativamente mais rápido do que outros algoritmos de classificação. Radix é especificamente para números inteiros, veja
?base::sort.list(x,method="radix")
. Esse também é um dos motivos pelos quaissetkey()
é rápido. Quando nenhuma chave é definida ou agrupamos em uma ordem diferente daquela da chave, chamamos isso de ad hoc por.3.3 Por que o agrupamento por colunas na chave é mais rápido do que um ad hoc por?
Porque cada grupo é contíguo na RAM, minimizando assim as buscas de páginas, e a memória pode ser copiada em massa (
memcpy
em C) em vez de loop em C.
A partir daqui, acho que definir uma chave de alguma forma permite que R use "classificação raiz" em vez de outros algoritmos, e é por isso que é mais rápido.
O guia de início rápido de 10 minutos também contém um guia sobre as teclas.
- Chaves
Vamos começar considerando data.frame, especificamente nomes de linhas (ou em inglês, nomes de linhas). Ou seja, os vários nomes pertencentes a uma única linha. Os vários nomes pertencentes a uma única linha? Não é a isso que estamos acostumados em data.frame. Sabemos que cada linha tem no máximo um nome. Uma pessoa tem pelo menos dois nomes, um primeiro nome e um segundo nome. Isso é útil para organizar uma lista telefônica, por exemplo, que é classificada pelo sobrenome e depois pelo nome. No entanto, cada linha em um data.frame pode ter apenas um nome.
Uma chave consiste em uma ou mais colunas de nomes de domínio, que podem ser inteiros, fatores, caracteres ou alguma outra classe, não simplesmente caracteres. Além disso, as linhas são classificadas pela chave. Portanto, um data.table pode ter no máximo uma chave, pois não pode ser classificado de mais de uma maneira.
A exclusividade não é imposta, ou seja, valores de chave duplicados são permitidos. Uma vez que as linhas são classificadas pela chave, quaisquer duplicatas na chave irão aparecer consecutivamente
A lista telefônica foi útil para entender o que é uma chave, mas parece que uma chave não é diferente quando comparada a ter uma coluna de fator. Além disso, não explica por que uma chave é necessária (especialmente para usar certas funções) e como escolher a coluna a ser definida como chave. Além disso, parece que em uma data.table com o tempo como coluna, definir qualquer outra coluna como chave provavelmente bagunçaria a coluna de tempo também, o que torna ainda mais confuso, pois não sei se tenho permissão para definir qualquer outra coluna como chave. Alguém pode me iluminar, por favor?