2010-07-16 107 views
6

我相信这是一个非常基本的问题:在R中,如何折叠类别或重新分类变量?

在RI有600000个分类变量 - 每一个被归类为“0”,“1”或“2”

我想do是折叠“1”和“2”并且自己留下“0”,使得在重新分类“0”=“0”之后; “1”=“1”和“2”=“1”---最后我只希望“0”和“1”作为每个变量的类别。

另外,如果可能的话,我宁愿不创建600,000个新变量,如果我可以用新的值替换现有的变量,那将是非常棒的!

这样做的最好方法是什么?

谢谢!

回答

4

有一个功能recode封装car(伴侣应用的退化):

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

或纯[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 

更新:重新编写所有类别列的数据帧tmp可以使用以下内容

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

谢谢你的回复!这就是我将其专门应用于数据的方式。我的数据是以data.frame的形式,我想要维护: data < - read.table(“k.csv”,header = TRUE,sep =“,”) dta < - data [ (1):0] col = dim(dta)[2] for(y in 1:col) py < - factor(pmin(as.data.frame(dta [,y]),2) ,标签= c(“0”,“1”)) py } 当然,这会导致错误 - 我确信我没有正确应用它 – CCA 2010-07-16 18:21:33

9

recode()对此有点矫枉过正。你的情况取决于它目前的编码方式。假设你的变量是x。

如果它的数字

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

,如果它是字符

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

是否与水平0,1,2

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

因素的任何那些可以在数据应用将dta框架到变量x的地方。例如...

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

或者,一个帧的多个列

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

我觉得这个用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 

新的水平矢量必须长度相同的数水平在x,所以你可以做更复杂的重新编码以及使用字符串和NA例如

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

需要注意的是,如果你只是想要的结果是0-1二元变量,你可以完全放弃因素:

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

第二条线还可以写得更简洁(但可能更含糊)作为

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

这就使你的因素一系列逻辑变量,用“0”映射FALSE和其他任何映射TRUEFALSETRUE将被大多数代码视为0和1,这反过来应该在分析中给出与使用具有“0”和“1”级别的因子基本相同的结果。事实上,如果给出相同的结果,这将在分析的正确性产生怀疑....

0

您可以使用sjmisc包的rec功能,可重新编码完整的数据框架立即(给定,所有变量至少有相同的recode值)。

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

我喜欢dplyr中的函数,它可以快速重新编码值。

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

希望这有助于:)