2010-07-16 13 views
6

Ich bin sicher, dass dies eine sehr grundlegende Frage ist:In R, wie Kategorien zu reduzieren oder Variablen neu zu kategorisieren?

In RI hat 600.000 kategorische Variablen - die jeweils als „0“ eingestuft ist, „1“ oder „2“

Was ich möchte do ist kollabieren "1" und "2" und lassen Sie "0" von selbst, so dass nach der Neukategorisierung "0" = "0"; "1" = "1" und "2" = "1" --- am Ende möchte ich nur "0" und "1" als Kategorien für jede der Variablen.

Wenn es mir möglich wäre, würde ich lieber nicht 600.000 neue Variablen erstellen, wenn ich die vorhandenen Variablen durch die neuen Werte ersetzen könnte, die toll wären!

Was wäre der beste Weg, dies zu tun?

Vielen Dank!

Antwort

4

Es gibt eine Funktion recode in Paket car (Companion to Applied Regression):

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

oder für Ihren Fall im Klar 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 

Update: alle kategorischen Spalten neu zu kodieren eines Datenrahmens tmp können Sie folgende

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

Vielen Dank für die Antwort! Dies ist, wie ich es speziell auf meine Daten anwende. Meine Daten liegen in Form eines data.frames vor, den ich gerne pflegen würde: data <- read.table ("k.csv", header = TRUE, sep = ",") dta <- daten [ , 1: 30] col = dim (dta) [2] für (y in 1: col) { py <- Faktor (pmin (as.data.frame (dta [, y]), 2) , Etiketten = c ("0", "1")) py } Natürlich führt das zu einem Fehler - ich bin mir sicher, dass ich es nicht richtig anwende – CCA

9

recode() ist ein wenig Overkill dafür. Dein Fall hängt davon ab, wie er aktuell codiert ist. Nehmen wir an, Ihre Variable ist x.

Wenn es numerische

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

wenn es Charakter ist

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

wenn es Faktor ist mit Ebenen 0,1,2

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

Jede dieser kann über eine Daten angewendet werden Rahmen dta an die Variable X an Ort und Stelle. Beispielsweise...

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

Oder mehrere Spalten eines Rahmens

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

finde ich noch mehr Generika ist factor(new.levels[x]) mit:

> 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 

Der neue Ebenen Vektor muss die gleiche Länge wie die Anzahl der Ebenen in x, so können Sie kompliziertere Recode auch mit Strings und NAs zum Beispiel

tun
0

Beachten Sie, dass, wenn Sie nur die Ergebnisse wollen 0-1 Binärgrößen sein, können Sie Faktoren ganz verzichten:

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

Die zweite Zeile kann auch kurz und bündig geschrieben werden (aber möglicherweise mehr kryptisch) als

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

Dies macht Ihre Faktoren in eine Reihe von logischen Variablen, mit „0“ Mapping FALSE und aller anderer Zuordnung zu TRUE. FALSE und TRUE werden von den meisten Codes als 0 und 1 behandelt, was wiederum im Wesentlichen das gleiche Ergebnis in einer Analyse ergeben sollte wie die Verwendung eines Faktors mit den Pegeln "0" und "1". In der Tat, wenn es nicht das gleiche Ergebnis, das würde Zweifel an der Richtigkeit der Analyse werfen ....

0

Sie die rec Funktion des Pakets sjmisc verwenden könnten, die ein vollständigen Daten neu codieren kann Frame auf einmal (vorausgesetzt, dass alle Variablen mindestens die gleichen recode-Werte haben).

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

Ich mochte die Funktion in dplyr, die Werte schnell recode kann.

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

this helps :)