2010-07-16 24 views
6

Tôi chắc chắn đây là một câu hỏi rất cơ bản:Trong R, cách thu gọn danh mục hoặc phân loại các biến?

Trong RI có 600.000 biến phân loại - mỗi trong số đó được phân loại là "0", "1" hoặc "2"

Những gì tôi muốn làm là thu gọn "1" và "2" và để lại "0" của chính nó, sao cho sau khi phân loại lại "0" = "0"; "1" = "1" và "2" = "1" --- cuối cùng tôi chỉ muốn "0" và "1" làm danh mục cho từng biến.

Ngoài ra, nếu có thể tôi không muốn tạo 600.000 biến mới, nếu tôi có thể thay thế các biến hiện tại bằng các giá trị mới sẽ tuyệt vời!

Cách tốt nhất để làm điều này là gì?

Cảm ơn bạn!

Trả lời

4

Có một chức năng recode trong gói car (Companion để Applied Regression):

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

hoặc đối với trường hợp của bạn ở đồng bằng 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 

Cập nhật: Để mã hóa lại tất cả các cột phân loại của khung dữ liệu tmp bạn có thể sử dụng

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

Cảm ơn bạn đã trả lời! Đây là cách tôi áp dụng nó vào dữ liệu của tôi một cách cụ thể. Dữ liệu của tôi ở dạng data.frame, mà tôi muốn duy trì: dữ liệu <- read.table ("k.csv", header = TRUE, sep = ",") dta <- data [ , 1: 30] col = dim (dta) [2] cho (y trong 1: col) { py <- factor (pmin (as.data.frame (dta [, y]), 2) , labels = c ("0", "1")) py } Tất nhiên dẫn đến lỗi - Tôi chắc chắn rằng tôi không áp dụng đúng cách – CCA

9

recode() là một chút quá mức cần thiết cho việc này. Trường hợp của bạn phụ thuộc vào cách nó hiện đang được mã hóa. Giả sử biến của bạn là x.

Nếu đó là số

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

nếu đó là nhân vật

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

nếu đó là yếu tố với các mức 0,1,2

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

Bất kỳ của những người có thể được áp dụng trên một dữ liệu khung dta đến biến x tại chỗ. Ví dụ...

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

Hoặc, nhiều cột của một khung

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

Tôi tìm thấy điều này thậm chí còn chung chung hơn sử dụng 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 

Mức vector mới phải cùng độ dài như số lượng các cấp trong x, vì vậy bạn có thể thực hiện các lần truy tìm phức tạp hơn cũng như sử dụng các chuỗi và các NA chẳng hạn

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

Lưu ý rằng nếu bạn chỉ muốn kết quả là 0-1 biến nhị phân, bạn có thể bỏ yếu tố hoàn toàn:

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

Dòng thứ hai cũng có thể được viết ngắn gọn hơn (nhưng có thể khó hiểu hơn) như

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

Điều này biến các yếu tố của bạn thành một loạt biến hợp lý, có ánh xạ "0" thành FALSE và mọi thứ khác ánh xạ tới TRUE. FALSETRUE sẽ được coi là 0 và 1 bởi hầu hết mã, do đó sẽ cung cấp cho kết quả cơ bản cùng một kết quả trong phân tích khi sử dụng hệ số với các mức "0" và "1". Trong thực tế, nếu nó không cho cùng một kết quả, điều đó sẽ nghi ngờ về tính chính xác của việc phân tích ....

0

Bạn có thể sử dụng chức năng rec của gói sjmisc, có thể mã hóa lại các dữ liệu hoàn chỉnh khung cùng một lúc (được cho, rằng tất cả các biến có ít nhất cùng một giá trị mã hóa).

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

Tôi thích hàm trong dplyr có thể nhanh chóng recode giá trị.

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

Hope this helps :)

Các vấn đề liên quan