In R, how to collapse categories or recategorize variables?

假如想象 提交于 2019-11-30 14:20:53

问题


I am sure this is a very basic question:

In R I have 600,000 categorical variables - each of which is classified as "0", "1", or "2"

What I would like to do is collapse "1" and "2" and leave "0" by itself, such that after re-categorizing "0" = "0"; "1" = "1" and "2" = "1" --- in the end I only want "0" and "1" as categories for each of the variables.

Also, if possible I would rather not create 600,000 new variables, if I can replace the existing variables with the new values that would be great!

What would be the best way to do this?

Thank you!


回答1:


There is a function recode in package car (Companion to Applied Regression):

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

or for your case in plain 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: To recode all categorical columns of a data frame tmp you can use the following

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



回答2:


I find this is even more generic using 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

The new levels vector must the same length as the number of levels in x, so you can do more complicated recodes as well using strings and NAs for example

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



回答3:


recode()'s a little overkill for this. Your case depends on how it's currently coded. Let's say your variable is x.

If it's numeric

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

if it's character

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

if it's factor with levels 0,1,2

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

Any of those can be applied across a data frame dta to the variable x in place. For example...

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

Or, multiple columns of a frame

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



回答4:


Note that if you just want the results to be 0-1 binary variables, you can forego factors altogether:

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

The second line can also be written more succinctly (but possibly more cryptically) as

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

This turns your factors into a series of logical variables, with "0" mapping to FALSE and anything else mapping to TRUE. FALSE and TRUE will be treated as 0 and 1 by most code, which in turn should give essentially the same result in an analysis as using a factor with levels "0" and "1". In fact, if it doesn't give the same result, that would cast doubt on the correctness of the analysis....




回答5:


You could use the rec function of the sjmisc package, which can recode a complete data frame at once (given, that all variables have at least the same recode-values).

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



回答6:


I liked the function in dplyr that can quickly recode values.

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

Hope this helps :)



来源:https://stackoverflow.com/questions/3267312/in-r-how-to-collapse-categories-or-recategorize-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!