Como fazer uma operação de mesclagem data.table
-
19-09-2019 - |
Pergunta
Nota: esta questão e as seguintes respostas referem-se a versões data.table <1.5.3; V. 1.5.3 foi lançado em fevereiro de 2011 para resolver este problema ver um tratamento mais recente (03-2012):. Traduzindo SQL junta-se em chaves estrangeiras para R data.table sintaxe
Eu estive cavando através da documentação para o href="http://cran.r-project.org/web/packages/data.table/index.html" dados . pacote de mesa (um substituto para data.frame que é muito mais eficiente para certas operações), incluindo apresentação de Josh Reich em SQL e data.table no NYC R Meetup (pdf), mas não consigo entender esta operação totalmente trivial fora.
> x <- DT(a=1:3, b=2:4, key='a')
> x
a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
> y <- DT(a=1:3, c=c('a','b','c'), key='a')
> y
a c
[1,] 1 a
[2,] 2 b
[3,] 3 c
> x[y]
a b
[1,] 1 2
[2,] 2 3
[3,] 3 4
> merge(x,y)
a b c
1 1 2 a
2 2 3 b
3 3 4 c
Os documentos dizem "Quando [o primeiro argumento] é em si um data.table, uma junção é invocado semelhante ao de base :: merge mas usa busca binária na chave de classificação." Claramente este não é o caso. Posso obter as outras colunas de y para o resultado de x [y] com data.tables? Parece que é só tomar as fileiras de x onde a chave corresponde a chave de y, mas ignorando o resto do y inteiramente ...
Solução
Você está citando a parte errada da documentação. Se você tem um olhar para o doc de [.data.table
você vai ler:
Quando i é um data.table, x deve ter um chave, o que significa juntar I a X e retorno as linhas de x que correspondem . Uma junção de igualdade é efectuada entre cada coluna em i a cada coluna na chave de x em ordem. Isto é semelhante à base de R funcionalidade do sub definindo uma matriz por uma matriz 2-coluna, e em maior dimensões Subdefinição um n-dimensional matriz por uma matriz n-coluna
Eu admito a descrição do pacote (a parte que você citou) é um pouco confuso, porque ele parece dizer que o "[" -operation pode ser usado em vez de mesclagem. Mas eu acho que o que diz é:. Se x e y são ambos data.tables usamos uma junção em um índice (que é invocado como merge) em vez de busca binária
Mais uma coisa:
A biblioteca data.table eu instalei via install.packages
estava faltando o merge.data.table method
, portanto, usando merge
chamaria merge.data.frame
. Após a instalação do pacote de R-Forge R usado o método mais rápido merge.data.table
.
Você pode verificar se você tem o método merge.data.table verificando a saída de:
methods(generic.function="merge")
EDIT [Answer já não é válida]: Esta resposta refere-se a versão data.table 1.3. Na versão 1.5.3 do comportamento de data.table mudado e x [y] devolve os resultados esperados. Obrigado Matthew Dowle , autor de data.table, para apontar isto nos comentários.
Outras dicas
Obrigado pelas respostas. Eu perdi esta discussão quando foi originalmente publicado. data.table mudou desde fevereiro. 1.4.1 foi liberado para CRAN um tempo atrás e 1.5 é sair em breve. Por exemplo, o apelido DT () foi substituída com a lista (); como um primitivo seu muito mais rápido, e data.table agora herda de data.frame assim que trabalha com pacotes que única aceitar data.frame como ggplot e rede, sem qualquer conversão necessária (mais rápido e mais conveniente ).
É possível subscrever a tag data.table então eu recebo um e-mail quando alguém postar uma pergunta com essa marca? A lista datatable-ajuda tem crescido para cerca de 30-40 mensagens por mês, mas estou feliz em responder aqui também se pode obter algum tipo de notificação.
Matthew
Acho que usando a função base::merge
não é necessário, como a utilização de data.table
junta pode ser muito mais rápido. Por exemplo. veja o seguinte. Eu faço x
e y
data.tables com 3-3 colunas:
x <- data.table( foo = 1:5, a=20:24, zoo = 5:1 )
y <- data.table( foo = 1:5, b=30:34, boo = 10:14)
setkey(x, foo)
setkey(y, foo)
E fundir ambos com base:merge
e data.table
junta para ver a velocidade de execuções:
system.time(merge(x,y))
## user system elapsed
## 0.027 0.000 0.023
system.time(x[,list(y,x)])
## user system elapsed
## 0.003 0.000 0.006
Os resultados não são idênticos, como o último tem uma coluna extra:
merge(x,y)
## foo a zoo b boo
## [1,] 1 20 5 30 10
## [2,] 2 21 4 31 11
## [3,] 3 22 3 32 12
## [4,] 4 23 2 33 13
## [5,] 5 24 1 34 14
x[,list(x,y)]
## foo a zoo foo.1 b boo
## [1,] 1 20 5 1 30 10
## [2,] 2 21 4 2 31 11
## [3,] 3 22 3 3 32 12
## [4,] 4 23 2 4 33 13
## [5,] 5 24 1 5 34 14
O que não poderia fazer um grande problema:)
Eu acho que f3lix está correto e que a documentação é um pouco enganador. O benefício é em fazer uma junção rápida para o subconjunto dos dados. Ainda em última análise, precisa usar a função merge
depois como no seu exemplo acima.
Você vai ver na apresentação de Josh sobre o uso de dados .table que esta é a forma como o seu exemplo é executado. Ele primeiros subconjuntos um dos data.tables, em seguida, faz uma mesclagem:
library(data.table)
sdt <- DT(series, key='series_id')
ddt <- DT(data, key='series_id')
u <- sdt[ grepl('^[A-Z]{2}URN', fred_id) & !grepl('DSURN', fred_id) ]
d <- ddt[ u, DT(min=min(value)), by='series_id', mult='all']
data <- merge(d,series)[,c('title','min','mean','max')]