Quando devo usar o operador: = em data.table?

88

data.tableobjetos agora têm um operador: =. O que torna este operador diferente de todos os outros operadores de atribuição? Além disso, quais são seus usos, quão mais rápido é e quando deve ser evitado?

Ari B. Friedman
fonte

Respostas:

94

Aqui está um exemplo mostrando 10 minutos reduzidos para 1 segundo (de NEWS na página inicial ). É como subatribuir a um, data.framemas não copia a tabela inteira todas as vezes.

m = matrix(1,nrow=100000,ncol=100)
DF = as.data.frame(m)
DT = as.data.table(m)

system.time(for (i in 1:1000) DF[i,1] <- i)
     user  system elapsed 
  287.062 302.627 591.984 

system.time(for (i in 1:1000) DT[i,V1:=i])
     user  system elapsed 
    1.148   0.000   1.158     ( 511 times faster )

Colocar o :=em jcomo isso permite que mais idiomas:

DT["a",done:=TRUE]   # binary search for group 'a' and set a flag
DT[,newcol:=42]      # add a new column by reference (no copy of existing data)
DT[,col:=NULL]       # remove a column by reference

e:

DT[,newcol:=sum(v),by=group]  # like a fast transform() by group

Não consigo pensar em nenhuma razão para evitar :=! Além de, dentro de um forloop. Como :=aparece dentro DT[...], vem com a pequena sobrecarga do [.data.tablemétodo; por exemplo, S3 expedição e a verificação da presença e tipo de argumentos, tais como i, by, nomatchetc. Assim, para dentro de forlaçadas, há uma sobrecarga baixo, versão directa de :=chamada set. Veja ?setpara mais detalhes e exemplos. As desvantagens de setincluir idevem ser números de linha (sem pesquisa binária) e você não pode combiná-lo com by. Fazer essas restrições setpode reduzir drasticamente a sobrecarga.

system.time(for (i in 1:1000) set(DT,i,"V1",i))
     user  system elapsed 
    0.016   0.000   0.018
Matt Dowle
fonte
26
Obrigado por desenvolver este pacote. Tenho a sensação de que revisarei muito do meu código para usar este pacote.
Iterador de
1
No chat me pediram para fazer / responder sozinho (o que aparentemente é encorajado ) - essa pergunta está aqui
Matt Dowle
4
@MatthewDowle Deseja incluir uma explicação de quando não usar: = e usar set () em vez disso?
Ari B. Friedman
2
@MatthewDowle Eu marcaria com +1 novamente se pudesse.
Ari B. Friedman
3
@jabberwocky Sem problemas. set(DT, i, "V1", i)define a "V1"coluna enquanto set(DT, i, colVar, i)define o nome da coluna contido na colVarvariável (por exemplo, se colVar = "V1"foi feito anteriormente). As aspas indicam que o nome da coluna deve ser interpretado literalmente, em vez de pesquisar a variável.
Matt Dowle de