2014-10-16 15 views
9

Ho il set di datimediano restituendo un errore quando si utilizza data.table in R

> head(DT) 
    V1 V2 V3 V4 V5  V6 V7 
1: 2 1 2 0.91 0.02 880.00 1 
2: 3 2 1 0.02 0.00 2.24 2 
3: 1 1 1 0.15 0.01 3.41 3 
4: 1 2 1 3.92 0.05 268.67 2 
5: 1 1 2 0.10 0.01 1.59 3 
6: 0 1 1 1.20 0.04 1.43 3 

> sapply(DT, class) 
     V1  V2  V3  V4  V5  V6  V7 
"integer" "integer" "integer" "numeric" "numeric" "numeric" "factor" 

che si estende per migliaia di righe seguente. Sto cercando di calcolare i valori mediani di V1-V6 all'interno degli 8 gruppi definiti per il fattore variabile V7

> levels(DT$V7) 
[1] "1" "2" "3" "4" "5" "6" "7" "8" 

Al momento sto usando il seguente comando, che restituisce un errore:

> DT[, lapply(.SD, median), by = V7] 
Error in `[.data.table`(DF, , lapply(.SD, median), by = V7) : 
Column 1 of result for group 4 is type 'integer' but expecting type 'double'. Column types must be consistent for each group. 

Ho letto da qualche parte che un modo per aggirare questo era usando as.double(median(X)). Ma questo funziona per le singole colonne: DT[, as.double(median(X)), by = V7], ma non quando si considera tutte le colonne: DT[, lapply(.SD, as.double(median)), by = V7] (come previsto, perché si deve passare un input per mediana)

posso andare in giro usando aggregato

> aggregate(DT[,c(1:6), with = FALSE], by = list(DF$V7), FUN = median) 
    Group.1 V1 V2 V3  V4 V5  V6 
    1  1 0 1 1 1.285 0.04 401.500 
    2  2 1 2 1 3.565 0.06 6.400 
    3  3 0 1 1 0.360 0.03 11.200 
    4  4 1 1 1 74.290 0.26 325.960 
    5  5 2 1 0 1.145 0.04 1.415 
    6  6 0 1 1 10.100 0.18 93.000 
    7  7 1 1 0 0.740 0.04 1.080 
    8  8 1 1 0 7.970 0.40 0.050 

ma mi piacerebbe sapere se c'è un modo per risolvere l'errore descritto in precedenza e fare questo calcolo utilizzando data.table

+0

Utilizzare il solito 'lapply' sintassi:' lapply (.SD, function (x) as.numeric (median (x))) '. Il secondo argomento di 'lapply' deve essere una funzione. – Roland

risposta

12

median è insolito in quanto può restituire diversi tipi di valori di ritorno per lo stesso tipo di ingresso:

The default method returns a length-one object of the same type as x, except when x is integer of even length, when the result will be double.

Tuttavia, data.table necessita di un tipo di valore di ritorno coerente. Avete due possibilità:

Converti tutte le colonne a numerico:

DT[, paste0("V", 1:6) := lapply(.SD, as.numeric), by = V7] 

o convertire il valore di ritorno di median:

DT[, lapply(.SD, function(x) as.numeric(median(x))), by = V7] 
Problemi correlati