2016-01-01 14 views

risposta

9

La conversione da factor a numeric fornisce i valori interi. Tuttavia, se le colonne factor hanno livelli specificati come c('b', 'a', 'c', 'd') o c('c', 'b', 'a'), i valori interi saranno nell'ordine indicato. Proprio al fine di evitare che, siamo in grado di specificare il levels chiamando il factor di nuovo (più sicuro)

df1[] <- lapply(df1, function(x) 
       as.numeric(factor(x, levels=letters[1:3]))) 

Se stiamo usando data.table, una possibilità potrebbe essere quella di utilizzare set. Sarebbe più efficiente per dataset di grandi dimensioni. La conversione in matrix potrebbe causare problemi di memoria.

library(data.table) 
setDT(df1) 
for(j in seq_along(df1)){ 
set(df1, i=NULL, j=j, 
    value= as.numeric(factor(df1[[j]], levels= letters[1:3]))) 
} 
+0

Sono curioso: come è DF1 [] <- ... Differiscono da df1 <-... Penso che portano allo stesso risultato, alla fine, ma forse da percorsi diversi? – atiretoo

+0

@atiretoo Conserva la struttura come nel set di dati originale. – akrun

+1

Aha! Grazie sì, in particolare, df1 sarà ancora un frame dati – atiretoo

11

Vorrei provare:

> mydf[] <- as.numeric(factor(as.matrix(mydf))) 
> mydf 
    V1 V2 V3 
1 1 2 3 
2 3 2 1 
3 3 2 3 
4 2 2 1 
+0

Puoi spiegare perché un semplice 'apply (mydf, 2, as.numeric)' non funziona? –

+0

@AlbertMasclans, leggi la prima riga della sezione "dettagli" per 'apply'. 'apply' prima fa' as.matrix' su 'data.frame' (che convertirà tutto in' character's). Se poi usi direttamente 'as.numeric' su un vettore' character', finirai con un gruppo di valori 'NA'. – A5C1D2H2I1M1N2O1R2T1

5

Questo approccio è simile a quello di Ananda, ma utilizza unlist() invece di factor(as.matrix()). Poiché tutte le tue colonne sono già fattori, unlist() le combinerà in un vettore fattore con i livelli appropriati.

Quindi diamo un'occhiata a cosa succede quando abbiamo unlist() il tuo data frame.

unlist(df, use.names = FALSE) 
# [1] a c c b b b b b c a c a 
# Levels: a b c 

Ora possiamo semplicemente eseguire as.integer() (o c()) sul codice di cui sopra, perché i valori interi dei fattori corrispondono la mappatura desiderata. E così il seguente rivaluterà l'intero frame dei dati.

df[] <- as.integer(unlist(df, use.names = FALSE)) 
## note that you can also just drop the factor class with c() 
## df[] <- c(unlist(df, use.names = FALSE)) 
df 
# V1 V2 V3 
# 1 1 2 3 
# 2 3 2 1 
# 3 3 2 3 
# 4 2 2 1 

Nota:use.names = FALSE non è necessario. Tuttavia, il rilascio dell'attributo names renderà questo processo più efficiente.

dati:

df <- structure(list(V1 = structure(c(1L, 3L, 3L, 2L), .Label = c("a", 
"b", "c"), class = "factor"), V2 = structure(c(1L, 1L, 1L, 1L 
), .Label = "b", class = "factor"), V3 = structure(c(2L, 1L, 
2L, 1L), .Label = c("a", "c"), class = "factor")), .Names = c("V1", 
"V2", "V3"), class = "data.frame", row.names = c(NA, -4L)) 
Problemi correlati