Tôi có khung dữ liệu với biến phân loại giữ liệt kê của chuỗi, có độ dài thay đổi (điều quan trọng là vì câu hỏi này sẽ trùng lặp với this hoặc this), ví dụ:R: tạo biến giả dựa trên biến phân loại * của danh sách *
df <- data.frame(x = 1:5)
df$y <- list("A", c("A", "B"), "C", c("B", "D", "C"), "E")
df
x y 1 1 A 2 2 A, B 3 3 C 4 4 B, D, C 5 5 E
Và hình thức mong muốn là một biến giả cho mỗi chuỗi duy nhất nhìn thấy bất cứ nơi nào trong df$y
, ví dụ:
data.frame(x = 1:5, A = c(1,1,0,0,0), B = c(0,1,0,1,0), C = c(0,0,1,1,0), D = c(0,0,0,1,0), E = c(0,0,0,0,1))
x A B C D E 1 1 1 0 0 0 0 2 2 1 1 0 0 0 3 3 0 0 1 0 0 4 4 0 1 1 1 0 5 5 0 0 0 0 1
cách tiếp cận ngây thơ này hoạt động:
> uniqueStrings <- unique(unlist(df$y))
> n <- ncol(df)
> for (i in 1:length(uniqueStrings)) {
+ df[, n + i] <- sapply(df$y, function(x) ifelse(uniqueStrings[i] %in% x, 1, 0))
+ colnames(df)[n + i] <- uniqueStrings[i]
+ }
Tuy nhiên nó rất xấu xí, lười biếng và chậm chạp với khung dữ liệu lớn.
Mọi đề xuất? Một cái gì đó ưa thích từ tidyverse
?
CẬP NHẬT: Tôi có 3 cách tiếp cận khác nhau bên dưới. Tôi đã thử nghiệm chúng bằng cách sử dụng system.time
trên máy tính xách tay (Windows 7, 32GB RAM) trên số liệu thực, bao gồm 1M hàng, mỗi hàng chứa danh sách có độ dài từ 1 đến 4 chuỗi (trong số ~ 350 giá trị chuỗi duy nhất), 200MB tổng thể trên đĩa. Vì vậy, kết quả mong đợi là một khung dữ liệu với kích thước 1M x 350. Các phương pháp tiếp cận tidyverse
(@Sotos) và base
(@ joel.wilson) mất quá lâu tôi phải khởi động lại R. Phương pháp tiếp cận qdapTools
(@akrun) tuy nhiên hoạt động tuyệt vời:
> system.time(res1 <- mtabulate(varsLists))
user system elapsed
47.05 10.27 116.82
Vì vậy, đây là phương pháp tôi sẽ đánh dấu là được chấp nhận.
hoặc 'data.frame (x = df $ y, hàm (l) {bảng (yếu tố (l, mức = LETTERS [1: 5]))}))) ' – alistaire
@alistaire có thể' cấp = duy nhất (không công khai (df $ y)) 'thay vì' LETTERS [1: 5] '? – Sotos
@Sotos Tôi đã có điều đó, nhưng đã tìm ra điều này là ít tính toán hơn. Tuyến đường tốt nhất là lưu trữ như một biến riêng biệt, nhưng điều đó sẽ yêu cầu một dòng thứ hai ... – alistaire