2010-07-16 16 views
6

Sono sicuro che questa è una domanda molto semplice:In R, come comprimere le categorie o ricategorizzare le variabili?

In RI hanno 600.000 variabili categoriali - ognuno dei quali è classificato come "0", "1", o "2"

Quello che vorrei do è collassare "1" e "2" e lasciare "0" da solo, in modo tale da riclassificare "0" = "0"; "1" = "1" e "2" = "1" --- alla fine voglio solo "0" e "1" come categorie per ciascuna delle variabili.

Inoltre, se possibile, preferirei non creare 600.000 nuove variabili, se posso sostituire le variabili esistenti con i nuovi valori che sarebbe fantastico!

Quale sarebbe il modo migliore per farlo?

Grazie!

risposta

4

c'è una funzione recode nel pacchetto car (Companion to regressione applicata):

require("car")  
recode(x, "c('1','2')='1'; else='0'") 

o per il vostro caso in pianura R:

> x <- factor(sample(c("0","1","2"), 10, replace=TRUE)) 
> x 
[1] 1 1 1 0 1 0 2 0 1 0 
Levels: 0 1 2 
> factor(pmin(as.numeric(x), 2), labels=c("0","1")) 
[1] 1 1 1 0 1 0 1 0 1 0 
Levels: 0 1 

Aggiornamento: ricodificare tutte le colonne categoriche di un frame di dati tmp è possibile utilizzare il seguente

recode_fun <- function(x) factor(pmin(as.numeric(x), 2), labels=c("0","1")) 
require("plyr") 
catcolwise(recode_fun)(tmp) 
+0

Grazie per la risposta! Questo è il modo in cui lo sto applicando specificamente ai miei dati. I miei dati sono sotto forma di data.frame, che vorrei conservare: data <- read.table ("k.csv", header = TRUE, sep = ",") dta <- data [ , 1: 30] col = dim (dta) [2] per (y in 1: col) { py <- factor (pmin (as.data.frame (dta [, y]), 2) , labels = c ("0", "1")) py } Ovviamente questo genera un errore - Sono sicuro che non lo sto applicando correttamente – CCA

9

recode() è un po 'eccessivo per questo. Il tuo caso dipende da come è attualmente codificato. Diciamo che la tua variabile è x.

Se è numerico

x <- ifelse(x>1, 1, x) 

se il suo carattere

x <- ifelse(x=='2', '1', x) 

se è fattore con livelli 0,1,2

levels(x) <- c(0,1,1) 

Qualsiasi di questi possono essere applicati attraverso un data frame dta alla variabile x in posizione. Per esempio...

dta$x <- ifelse(dta$x > 1, 1, dta$x) 

Oppure, più colonne di una cornice

df[,c('col1','col2'] <- sapply(df[,c('col1','col2'], FUN = function(x) ifelse(x==0, x, 1)) 
12

Trovo che questo è ancora più generico utilizzando factor(new.levels[x]):

> x <- factor(sample(c("0","1","2"), 10, replace=TRUE)) 
> x 
[1] 0 2 2 2 1 2 2 0 2 1 
Levels: 0 1 2 
> new.levels<-c(0,1,1) 
> x <- factor(new.levels[x]) 
> x 
[1] 0 1 1 1 1 1 1 0 1 1 
Levels: 0 1 

i nuovi livelli vettore deve la stessa lunghezza del numero di livelli in x, quindi puoi eseguire anche ricodifiche più complicate utilizzando stringhe e NA, ad esempio

x <- factor(c("old", "new", NA)[x]) 
> x 
[1] old <NA> <NA> <NA> new <NA> <NA> old 
[9] <NA> new  
Levels: new old 
0

Si noti che se si desidera solo i risultati per essere 0-1 variabili binarie, è possibile rinunciare a fattori del tutto:

f <- sapply(your.data.frame, is.factor) 
your.data.frame[f] <- lapply(your.data.frame[f], function(x) x != "0") 

La seconda linea può anche essere scritta più sinteticamente (ma forse più criptico) come

your.data.frame[f] <- lapply(your.data.frame[f], `!=`, "0") 

Questa operazione accende il fattori in una serie di variabili logiche, con "0" mappatura FALSE e quant'altro mappatura TRUE. FALSE e TRUE verranno considerati come 0 e 1 dalla maggior parte del codice, che a sua volta dovrebbe dare essenzialmente lo stesso risultato in un'analisi come utilizzando un fattore con livelli "0" e "1". Infatti, se non si dare lo stesso risultato, che sarebbe messo in dubbio la correttezza delle analisi ....

0

è possibile utilizzare la funzione rec del pacchetto sjmisc, che può ricodificare un completo di dati frame in una volta (dato che tutte le variabili hanno almeno gli stessi valori di ricodifica).

library(sjmisc) 
mydf <- data.frame(a = sample(0:2, 10, T), 
        b = sample(0:2, 10, T), 
        c = sample(0:2, 10, T)) 

> mydf 
    a b c 
1 1 1 0 
2 1 0 1 
3 0 2 0 
4 0 1 0 
5 1 0 0 
6 2 1 1 
7 0 1 1 
8 2 1 2 
9 1 1 2 
10 2 0 1 

mydf <- rec(mydf, "0=0; 1,2=1") 

    a b c 
1 1 1 0 
2 1 0 1 
3 0 1 0 
4 0 1 0 
5 1 0 0 
6 1 1 1 
7 0 1 1 
8 1 1 1 
9 1 1 1 
10 1 0 1 
0

Mi è piaciuta la funzione in dplyr che può ricodificare rapidamente i valori.

library(dplyr) 
df$x <- recode(df$x, old = "new") 

Spero che questo aiuti :)

Problemi correlati