2012-12-23 4 views
13

La mia domanda è relativa a this one per quanto riguarda i dati categoriali (fattori in termini R) quando si utilizza il pacchetto Caret. Capisco dal post collegato che se si utilizza la "interfaccia formula", alcune caratteristiche possono essere fattori e la formazione funzionerà correttamente. La mia domanda è: come posso scalare i dati con la funzione preProcess()? Se provo e farlo su un telaio di dati con alcune colonne come fattori, ottengo questo messaggio di errore:Come preelaborare le funzionalità quando alcune di esse sono fattori?

Error in preProcess.default(etitanic, method = c("center", "scale")) : 
    all columns of x must be numeric 

Vedi qui alcuni esempi di codice:

library(earth) 
data(etitanic) 

a <- preProcess(etitanic, method=c("center", "scale")) 
b <- predict(etitanic, a) 

Grazie.

risposta

18

È davvero lo stesso problema del post a cui ci si collega. preProcess funziona solo su dati numerici e si dispone di:

> str(etitanic) 
'data.frame': 1046 obs. of 6 variables: 
$ pclass : Factor w/ 3 levels "1st","2nd","3rd": 1 1 1 1 1 1 1 1 1 1 ... 
$ survived: int 1 1 0 0 0 1 1 0 1 0 ... 
$ sex  : Factor w/ 2 levels "female","male": 1 2 1 2 1 2 1 2 1 2 ... 
$ age  : num 29 0.917 2 30 25 ... 
$ sibsp : int 0 1 1 1 1 0 1 0 2 0 ... 
$ parch : int 0 2 2 2 2 0 0 0 0 0 ... 

Non si può centrare e la scala pclass o sex come-è così hanno bisogno di essere convertiti in variabili dummy. È possibile utilizzare model.matrix o accento circonflesso di dummyVars per fare questo:

> new <- model.matrix(survived ~ . - 1, data = etitanic) 
> colnames(new) 
[1] "pclass1st" "pclass2nd" "pclass3rd" "sexmale" "age"  
[6] "sibsp"  "parch" 

Il -1 si libera del intercetta. Ora è possibile eseguire preProcess su questo oggetto.

btw che fa preProcess ignora i dati non numerici è nella mia lista "da fare" ma potrebbe causare errori per le persone che non prestano attenzione.

Max

+1

Penso che abbiamo bisogno solo di due variabili per pclass. ("pclass1st, pclass2nd" o "pclass2nd, pclass3rd" o "pclass3rd, pclass1st"). Come in caso di sesso variabile, abbiamo considerato solo sexmale e sexfemale scartati. Correggimi se non è sufficiente – Sandeep

+0

@topepo, penso che la risposta qui sotto ignori l'elenco delle cose da fare. Suggerirei di aggiungere alcuni avvertimenti per le persone che non presterebbero attenzione. –

5

Ecco un modo veloce per escludere fattori o qualunque gradireste dalla considerazione:

set.seed(1) 
N <- 20 
dat <- data.frame( 
    x = factor(sample(LETTERS[1:5],N,replace=TRUE)), 
    y = rnorm(N,5,12), 
    z = rnorm(N,-5,17) + runif(N,2,12) 
) 

#' Function which wraps preProcess to exclude factors from the model.matrix 
ppWrapper <- function(x, excludeClasses=c("factor"), ...) { 
    whichToExclude <- sapply(x, function(y) any(sapply(excludeClasses, function(excludeClass) is(y,excludeClass)))) 
    processedMat <- predict(preProcess(x[!whichToExclude], ...), newdata=x[!whichToExclude]) 
    x[!whichToExclude] <- processedMat 
    x 
} 

> ppWrapper(dat) 
    x   y   z 
1 C 1.6173595 -0.44054795 
2 A -0.2933705 -1.98856921 
3 C 1.2177384 0.65420288 
4 D -0.8710374 0.62409408 
5 D -0.4504202 -0.34048640 
6 D -0.6943283 0.24236671 
7 E 0.7778192 0.91606677 
8 D 0.2184563 -0.44935163 
9 C -0.3611408 0.26075970 
10 B -0.7066441 -0.23046073 
11 D -1.5154339 -0.75549761 
12 D 0.4504825 0.38552988 
13 B 1.5692675 0.04093040 
14 C 0.4127541 0.13161807 
15 D 0.5426321 1.09527418 
16 B -2.1040322 -0.04544407 
17 C 0.6928574 1.12090541 
18 B 0.3580960 1.91446230 
19 E 0.3619967 -0.89018040 
20 A -1.2230522 -2.24567237 

È possibile passare tutto quello che vuoi in ppWrapper e otterrà passava a preProcess.

+0

Bella risposta! Penso che dovresti usare l'esempio dato (invece di un esempio artificiale che potrebbe confondere). Fondamentalmente, 'library (terra); dati (etitanici); ppWrapper (etitanic) ' –