2016-04-05 8 views
5

Come creare una nuova colonna con il rapporto tra 800 e 700 canali? Mi trovo spesso a dover affrontare questi tipi di problemi, con dati molto più complessi. Altri esempi potrebbero essere sottrarre il canale 800 dello stesso tempo dal canale 700 dello stesso tempo.Come eseguire un'operazione su due gruppi nella stessa data.table, dove entrambi i gruppi devono entrambi essere referenziati nel campo j

Esempio:

kdat <- data.table(channel=c(rep(c(700,800), each = 3)), 
        time=c(rep(1:3,2)), 
        value=c(1:6)) 

    channel time value 
1:  700 1  1 
2:  700 2  2 
3:  700 3  3 
4:  800 1  4 
5:  800 2  5 
6:  800 3  6 

Opzioni posso vedere sono:
1.) Spostare da lungo a grande formato e poi dividere, quindi converte di nuovo a lungo.
- Non mi piace perché devo andare avanti e indietro tra lungo e largo.
nota: torno a tanto tempo che mi piace mantenere tutti i dati insieme, e posso fare tutto il tracciamento da un singolo data.table.

2.) kdat [== canale 800, (valore).]/Kdat [canale == 700, (valore).]
- Non mi piace questo perché non c'è il controllo al fine di garantire gli stessi tempi ecc. sono abbinati.

3.) C'è un modo per farlo con .SD o in qualche altro modo che mi manca?

output desiderato:

channel time value ratio 
1: 700  1 1  4 
... 
6: 800  3 6  2 
+4

'kdat [, valore [canale == 800]/valore [canale == 700], per = tempo]'? – MichaelChirico

+0

@MichaelChirico sì che funziona, leggera modifica per ottenere l'output desiderato: 'kdat [, rapporto: = valore [canale == 800]/valore [canale == 700], per = tempo]' – kbarreto

risposta

2

io probabilmente fare

setkey(kdat, time) 
kdat[ 
    dcast(kdat, time~channel, value="value")[, rat := `800`/`700`], 
    rat := i.rat 
] 

Quindi stai cambiando da lungo a largo, ma solo in questa tabella temporanea utilizzata per la fusione, e solo con i tre colonne rilevanti (tempo, canale e valore).


Se sei sicuro che ogni volta che appare per un canale appare per l'altro, si può fare

kdat[order(channel, time), rat := with(split(value, channel), `800`/`700`)] 
+1

Non sono sicuro se questo è ciò che il L'OP aveva già in mente il problema numero 1. – Frank

0

Beh, se è necessario utilizzare .SD :)

kdat[, copy(.SD)[.SD[channel == 800 
        ][.SD[channel == 700], 
        rat := value/i.value, on='time' 
        ], rat := i.rat, on='time']][] 
Problemi correlati