2012-02-29 29 views
7

Tengo una matriz lógica x con filas con nombre ('a' y 'b') y columnas con nombre ('10', '20', '30', '40'). Digamos, esto:R: ¿cómo obtener los nombres de fila y columna de los elementos verdaderos de una matriz?

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"))) 

¿Hay un camino corto para conseguir una mesa que una lista de nombres de filas y columnas en las que tengo verdaderos valores? Es decir, quiero obtener la siguiente tabla:

a 10, 30 
b 20, 40 

Algo similar se puede obtener por which(x, arr.ind = T), que produce

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

Pero realmente quiero conseguir la primera tabla.

Respuesta

11

Puede usar directamente apply.

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

1: 't (t (aplicable (m, 1, función (U) Pegar (nombres (que (u)), colapso = ",")))) 'está aún más cerca del resultado solicitado y hay otros ajustes – Henry

2

No especificó esto, pero su salida deseada requerirá que supongamos que el resultado es de hecho rectangular. A saber, que no obtenemos 3 nombres de columna para a y solo 2 nombres de columna para b.

creo que esto debería empezar, al menos:

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 

que devuelve la información que desea, pero en un formato más seguro "larga", que no se ahogue en el caso no rectangular. Una vez allí, se podía volver a organizarla según sus especificaciones así:

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

pero francamente eso último me parece muy feo, y no me sorprendería que una mejor solución aparece si se espera un poco .

0

Puede utilizar el hecho de que table objetos se convierten en tramas de datos "largos" formato por 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) 

El resultado df es la siguiente:

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 

¿Qué le puede indexar para mantener solo TRUE filas:

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

Puede utilizar dplyr para convertir esto en exactamente la tabla que desea:

library(plyr) 
ddply(df, "Var1", function(x) x$Var2) 
    Var1 V1 V2 
1 a 10 30 
2 b 20 40 
Cuestiones relacionadas