2016-04-22 11 views
5

Ho una tabella dati e sto cercando di creare una nuova variabile che è una funzione di tutte le altre colonne. Un esempio semplificato sarebbe se volessi semplicemente sommare o prendere una media su tutte le righe. Per esempio:Utilizzare by = ogni riga per la tabella dati

dt <- data.table(a = 1:9, b = seq(10,90,10), c = seq(11:19), d = seq(100, 900, 100)) 

Voglio creare un vettore/colonna che è semplicemente la media di tutte le colonne. La sintassi che ci penso sarebbe simile a questa:

dt[, average := mean(.SD)] 

Tuttavia, questo riassume il tutto. So che posso anche fare:

dt[, average := lapply(.SD, mean)] 

Ma questo dà un risultato a riga singola. Sto cercando essenzialmente per l'equivalente di:

dt[, average := lapply(.SD, mean), by = all] 

tale che calcola semplicemente questo per tutte le righe, senza dover creare una colonna "id" e facendo tutto il mio calcolo per quella colonna. È possibile?

+1

Penso che il solito modo potrebbe essere 'dt [, m: = Riduci (\' + \ ', .SD)/lunghezza (.SD)]'. Se stai facendo operazioni a row, però, forse dovresti usare una matrice. – Frank

risposta

5

Il seguente codice data.table ha funzionato per me.

dt[, average := rowMeans(.SD)] 

Come sottolineato da @jangorecki, è possibile costruire la propria funzione per eseguire per riga, purché si ricordi che ogni riga è un oggetto lista:

# my function, must unlist the argument 
myMean <- function(i, ...) mean(unlist(i), ...) 

utilizzando by=seq_len

dt[, averageNew := myMean(.SD), by = seq_len(nrow(dt))] 

utilizzando row.names

dt[, averageOther := myMean(.SD), by = row.names(dt)] 
+0

Bello, me ne ricorderò questo. Però, in realtà ho una funzione personalizzata che volevo usare. È possibile fare qualcosa di simile in quel caso? Ad esempio: dt [, output: = miafunzione (.SD)] – Brandon

+0

Con una funzione personalizzata, è meglio seguire il metodo di @ señor-o. – lmo

+3

@lmo con funzione personalizzata potrebbe essere meglio usare solo 'dt [, a: = f (.SD), by = seq_len (nrow (dt))]' – jangorecki

3

Penso che una soluzione molto migliore sia solo per utilizzare apply per questo, che è stato creato per operazioni a matrice di righe come se non lo fosse lo data.table.

> dt$average = apply(dt, 1, mean) 
> dt 

    a b c d average 
1: 1 10 1 100  28 
2: 2 20 2 200  56 
3: 3 30 3 300  84 
4: 4 40 4 400  112 
5: 5 50 5 500  140 
6: 6 60 6 600  168 
7: 7 70 7 700  196 
8: 8 80 8 800  224 
9: 9 90 9 900  252 
Problemi correlati