2012-02-29 18 views
7

Tôi có ma trận lôgic x với các hàng được đặt tên ('a' và 'b') và các cột được đặt tên ('10', '20', '30', '40'). Giả sử, điều này:R: làm thế nào để có được tên hàng và cột của các yếu tố thực sự của một ma trận?

10 20 30 40 
a T F T F 
b F T F T 

structure(c(TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE), 
.Dim = c(2L, 4L), .Dimnames = list(c("a", "b"), c("10", "20", "30", "40"))) 

Có cách nào ngắn để lấy bảng liệt kê tên hàng và cột mà tôi có giá trị thực? Đó là, tôi muốn để có được bảng sau:

a 10, 30 
b 20, 40 

Something tương tự có thể thu được bằng cách which(x, arr.ind = T), trong đó sản xuất

row col 
a 1 1 
b 2 2 
a 1 3 
b 2 4 

Nhưng tôi thực sự muốn có được bảng đầu tiên.

Trả lời

11

Bạn có thể trực tiếp sử dụng apply.

apply(
    x, 1, 
    function(u) paste(names(which(u)), collapse=",") 
) 
+2

+1: 't (t (áp dụng (m, 1, chức năng (u) dán (tên (mà (u)), collapse = ",")))) 'thậm chí còn gần với kết quả được yêu cầu hơn và có thêm các chỉnh sửa – Henry

2

Bạn không chỉ định điều này, nhưng đầu ra mong muốn của bạn sẽ yêu cầu chúng tôi giả định rằng kết quả là trên thực tế hình chữ nhật. Cụ thể là chúng tôi không có 3 tên cột cho một và chỉ có 2 tên cột cho b.

Tôi nghĩ rằng điều này sẽ giúp bạn bắt đầu, ít nhất là:

m <- structure(c(TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE), 
.Dim = c(2L, 4L), .Dimnames = list(c("a", "b"), c("10", "20", "30", "40"))) 

rr <- rownames(m)[row(m)[which(m)]] 
cc <- colnames(m)[col(m)[which(m)]] 

dd <- data.frame(rr = rr,cc = cc) 
dd 

mà trả về thông tin mà bạn muốn, nhưng trong một định dạng an toàn hơn "dài", mà sẽ không bị nghẹt thở về vụ việc phi hình chữ nhật. Khi đó, bạn có thể tổ chức lại nó như bạn đã xác định như thế này:

library(plyr) 
ddply(dd,.(rr),function(x){ x$cc }) 

nhưng thẳng thắn mà bit cuối cùng tôi thấy thực sự xấu xí, và tôi sẽ không ngạc nhiên nếu một giải pháp tốt hơn bật lên nếu bạn chờ đợi một chút .

0

Bạn có thể sử dụng thực tế là table đối tượng được chuyển đổi thành "dài" khung dữ liệu định dạng bởi as.data.frame():

# Create matrix of interest 
mat <- structure(c(TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE), .Dim = c(2L, 4L), .Dimnames = list(c("a", "b"), c("10", "20", "30", "40"))) 

# Convert to table, then to long data.frame 
df <- mat %>% as.table %>% as.data.frame(., stringsAsFactors=FALSE) 

Các kết quả df như sau:

Var1 Var2 Freq 
1 a 10 TRUE 
2 b 10 FALSE 
3 a 20 FALSE 
4 b 20 TRUE 
5 a 30 TRUE 
6 b 30 FALSE 
7 a 40 FALSE 
8 b 40 TRUE 

Mà bạn khi đó, chỉ có thể lập chỉ mục để giữ TRUE hàng:

df <- df[df$Freq,1:2] %>% sort 
df 
     Var1 Var2 
    1 a 10 
    5 a 30 
    4 b 20 
    8 b 40 

Bạn có thể sử dụng dplyr để chuyển đổi này vào một cách chính xác bảng bạn muốn:

library(plyr) 
ddply(df, "Var1", function(x) x$Var2) 
    Var1 V1 V2 
1 a 10 30 
2 b 20 40 
Các vấn đề liên quan