2016-09-13 20 views
5

Tôi quan tâm đến việc lấy cột của một data.frame nơi các giá trị trong cột được phân cách bằng đường ống và tạo biến giả từ các giá trị được phân tách bằng đường ống.Chuyển đổi cột với dữ liệu phân cách đường ống thành các biến giả

Ví dụ:

Hãy nói rằng chúng ta bắt đầu với

df = data.frame(a = c("Ben|Chris|Jim", "Ben|Greg|Jim|", "Jim|Steve|Ben")) 

> df 
       a 
1 Ben|Chris|Jim 
2 Ben|Greg|Jim 
3 Jim|Steve|Ben 

Tôi quan tâm đến kết thúc với:

df2 = data.frame(Ben = c(1, 1, 1), Chris = c(1, 0, 0), Jim = c(1, 1, 1), Greg = c(0, 1, 0), 
       Steve = c(0, 0, 1)) 
> df2 
    Ben Chris Jim Greg Steve 
1 1  1 1 0  0 
2 1  0 1 1  0 
3 1  0 1 0  1 

Tôi không biết trước có bao nhiêu tiềm năng giá trị có trong lĩnh vực này. Trong ví dụ trên, biến "a" có thể bao gồm 1 giá trị hoặc 10 giá trị. Giả sử đây là một số hợp lý (tức là, < 100 giá trị có thể).

Bất kỳ cách nào tốt để thực hiện việc này?

Trả lời

6

Một cách khác là sử dụng cSplit_e từ splitstackshape gói.

tách khung dữ liệu theo cột afill bằng 0 và drop cột gốc.

library(splitstackshape) 
cSplit_e(df, "a", "|", type = "character", fill = 0, drop = T) 

# a_Ben a_Chris a_Greg a_Jim a_Steve 
#1  1  1  0  1  0 
#2  1  0  1  1  0 
#3  1  0  0  1  1 
+1

điều tuyệt vời nhất. –

+1

Rất nhiều câu trả lời tuyệt vời - cảm ơn tất cả mọi người. Tôi thích cái này nhất vì nó đơn giản nhất. Cảm ơn! – dreww2

6

Đây là một lựa chọn sử dụng dplyrtidyr:

library(dplyr) 
library(tidyr) 
df %>% tibble::rownames_to_column(var = "id") %>% 
     mutate(a = strsplit(as.character(a), "\\|")) %>% 
     unnest() %>% table() 

# a 
# id Ben Chris Greg Jim Steve 
# 1 1  1 0 1  0 
# 2 1  0 1 1  0 
# 3 1  0 0 1  1 

Các tương tự trong cơ sở R là:

df$a <- as.character(df$a) 
s <- strsplit(df$a, "|", fixed=TRUE) 
table(id = rep(1:nrow(df), lengths(s)), v = unlist(s)) 

dữ liệu:

df = data.frame(a = c("Ben|Chris|Jim", "Ben|Greg|Jim", "Jim|Steve|Ben")) 
2

Chúng ta có thể sử dụng mtabulate từ qdapTools sau khi tách 'a' cột

library(qdapTools) 
mtabulate(strsplit(as.character(df$a), "|", fixed = TRUE)) 
# Ben Chris Greg Jim Steve 
#1 1  1 0 1  0 
#2 1  0 1 1  0 
#3 1  0 0 1  1 
0

Đây là một phương pháp trong cơ sở R

# get unique set of names 
myNames <- unique(unlist(strsplit(as.character(df$a), split="\\|"))) 
# get indicator data.frame 
setNames(data.frame(lapply(myNames, function(i) as.integer(grepl(i, df$a)))), myNames) 

trả về

Ben Chris Jim Greg Steve 
1 1  1 1 0  0 
2 1  0 1 1  0 
3 1  0 1 0  1 

Các dòng đầu tiên sử dụng strsplit để tạo danh sách các tên được phân tách trên đường ống "|", unlistunique tạo ra một vectơ các tên duy nhất. Dòng thứ hai chạy qua các tên này với lapply và sử dụng grepl để tìm kiếm các tên, trong đó as.integer chuyển đổi thành các số nguyên nhị phân. Danh sách trả lại được chuyển đổi thành một data.frame và các tên cột được cung cấp với setNames.

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