2013-05-12 4 views
5

ho questo codice:colonna appena aggiunta nel 'j' di data.table dovrebbe essere disponibile nel campo di applicazione

dat<-dat[,list(colA,colB 
        ,RelativeIncome=Income/.SD[Nation=="America",Income] 
        ,RelativeIncomeLog2=log2(Income)-log2(.SD[Nation=="America",Income])) #Read 1) 
       ,by=list(Name,Nation)] 

1) Vorrei poter dire "RelativeIncomeLog2=log2(RelativeIncome)", ma "RelativeIncome" non è disponibile in Lo scopo di j?

2) Ho provato invece quanto segue (secondo le FAQ di data.table). Ora "RelativeIncome" è disponibile, ma non aggiunge le colonne:

 dat<-dat[,{colA;colB;RelativeIncome=Income/.SD[Nation=="America",Income]; 
       ,RelativeIncomeLog2=log2(RelativeIncome)])) 
       ,by=list(Name,Nation)] 
+1

La risposta di Ricardo probabilmente lo chiarisce, ma la funzione 'J()' non è la stessa cosa dell'argomento 'j' di' [.data.table'. Prova ''? J'' e ''? '[.data.table'' 'per i dettagli. 'J()' è per i join nell'argomento 'i' di' [.data.table'. – Frank

+0

Vedere anche [Come valutare (o creare) una colonna al volo in data.table in r] (https://stackoverflow.com/questions/15712858/how-can-i-evaluate-or-create-an -on-the-fly-column-in-data-table-in-r) – Henrik

risposta

8

È possibile creare e assegnare gli oggetti in j, basta usare { parentesi graffe }.

È quindi possibile passare questi oggetti (o funzioni & calcoli degli oggetti) da j e assegnarli come colonne di data.table. Per assegnare più di una volta colonna alla volta, semplicemente:

  • avvolgere il LHS in c(.)assicurarsi i nomi delle colonne sono stringhe e
  • l'ultima linea di j (cioè, il valore di "ritorno") dovrebbe essere una lista.

dat[ , c("NewIncomeComlumn", "AnotherNewColumn") := { 
       RelativeIncome  <- Income/.SD[Nation == "A", Income]; 
       RelativeIncomeLog2 <- log2(RelativeIncome); 
       ## this last line is what will be asigned. 
       list(RelativeIncomeLog2 * 100, c("A", "hello", "World")) 
       # assigned values are recycled as needed. 
       # If the recycling does not match up, a warning is issued. 
       } 
       , by = list(Name, Nation) 
       ] 

Puoi losely pensare j come una funzione all'interno dell'ambiente di dat

È inoltre possibile ottenere molto di più sofisticato e complesso, se necessario. È anche possibile incorporare by argomenti pure, utilizzando by=list(<someName>=col)

Infatti, simile alle funzioni, semplicemente creando un oggetto in j assegnando il valore, non significa che sarà disponibile al di fuori di j. Per poter essere assegnato a data.table, devi restituirlo. j restituisce automaticamente l'ultima riga; se quest'ultima riga è una lista, ogni elemento della lista sarà trattato come una colonna. Se si assegna per riferimento (ad esempio, utilizzando :=), si otterranno i risultati attesi.


In una nota separata, ho notato quanto segue nel codice:

Income/.SD[Nation == "America", Income] 

# Which instead could simply be: 
Income/Income[Nation == "America"] 

.SD è grande in quanto si tratta di una meravigliosa stenografia. Tuttavia, per invocarlo senza aver bisogno di tutte le colonne che incapsula è necessario sovraccaricare il codice con costi di memoria aggiuntivi. Se si utilizza solo una singola colonna, prendere in considerazione la denominazione di tale colonna in modo esplicito o aggiungere l'argomento .SDcols (dopo j) e denominare le colonne necessarie.

+0

forse una domanda stupida .. ma ciò che nel tuo esempio solo "RelativeIncomeLog2 * 100" verrà assegnato a una NewIncomeColumn. Ma cosa succede se voglio 2 nuove colonne corrispondenti a "RelativeIncome" e "RelativeIncomeLog2 * 100"? – varuman

+0

@varuman, non una domanda stupida. La risposta breve è di racchiudere la riga finale in 'list (.)' Vedere la modifica sopra per i dettagli. –

+0

@RicardoSaporta, penso che sia un errore avere 'by = ...' entro la fine '}'? Non dovrebbe venire dopo l'istruzione 'list (.)'? – Arun

Problemi correlati