2010-07-16 5 views
6

Je suis sûr que c'est une question fondamentale:R, comment réduire les catégories ou les variables recatégoriser?

En RI ont 600.000 variables - dont chacune est classé comme « 0 », « 1 » ou « 2 »

Ce que je voudrais faire est effondrement « 1 » et « 2 » et laisser « 0 » par lui-même, de telle sorte que, après re-classer « 0 » = « 0 »; « 1 » = « 1 » et « 2 » = « 1 » --- à la fin, je veux seulement « 0 » et « 1 » en tant que catégories pour chacune des variables.

Aussi, si possible, je préfère ne pas créer 600 000 nouvelles variables, si je peux remplacer les variables existantes par les nouvelles valeurs qui seraient géniales!

Quelle serait la meilleure façon de faire cela?

Merci!

Répondre

4

Il y a une fonction recode dans le paquet car (Companion to Applied Regression):

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

ou pour votre cas en R simple:

> 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 

Mise à jour: recoder toutes les colonnes catégoriques d'une trame de données tmp vous pouvez utiliser la

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

Merci pour la réponse! C'est ainsi que je l'applique spécifiquement à mes données. Mes données sont sous la forme d'un data.frame, que je voudrais maintenir: data <- read.table ("k.csv", en-tête = TRUE, sep = ",") dta <- data [ , 1: 30] col = dim (dta) [2] pour (y dans 1: col) { py <- facteur (pmin (comme.data.frame (dta [, y]), 2) , labels = c ("0", "1")) py } Bien sûr, cela entraîne une erreur - Je suis sûr que je ne l'applique pas correctement – CCA

9

recodage() est un peu exagéré pour cela. Votre cas dépend de la façon dont il est actuellement codé. Disons que votre variable est x.

Si elle est numérique

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

si son caractère

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

si elle est facteur avec des niveaux 0,1,2

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

Tout de ceux-ci peuvent être appliquées sur une des données frame dta à la variable x en place. Par exemple...

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

Ou, plusieurs colonnes d'un cadre

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

Je trouve cela est encore plus générique en utilisant 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 

Le nouveau vecteur de niveaux doit la même longueur que le nombre de niveaux en x, de sorte que vous pouvez faire des recodes plus compliquées ainsi en utilisant des chaînes et NA par exemple

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

Notez que si vous voulez juste que les résultats soient 0-1 variables binaires, vous pouvez renoncer à des facteurs tout à fait:

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

La deuxième ligne peut également être écrit de manière plus succincte (mais peut-être plus cryptique) comme

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

Cela transforme vos facteurs en une série de variables logiques, avec « 0 » à la cartographie FALSE et quoi que ce soit d'autre à la cartographie TRUE. FALSE et TRUE seront traités comme 0 et 1 par la plupart du code, ce qui devrait donner essentiellement le même résultat dans une analyse que d'utiliser un facteur avec des niveaux "0" et "1". En fait, si elle ne donnent le même résultat, qui remettrait en question l'exactitude de l'analyse ....

0

Vous pouvez utiliser la fonction rec du paquet sjmisc, qui peut recoder une donnée complète frame à la fois (étant donné que toutes les variables ont au moins les mêmes valeurs de recodage).

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

J'ai aimé la fonction dans dplyr qui peut rapidement recoder des valeurs.

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

Hope this helps :)

Questions connexes