2010-07-16 93 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") 

希望這有助於:)