2011-04-28 12 views
15

Tengo una matriz de distancias con los siguientes pasos:convertir y guardar matriz de distancia a un formato específico

x <- read.table(textConnection(' 
    t0 t1 t2 
aaa 0 1 0 
bbb 1 0 1 
ccc 1 1 1 
ddd 1 1 0 
'), header=TRUE) 

Como tal x es una trama de datos con las columnas y filas cabeceras

t0 t1 t2 
aaa 0 1 0 
bbb 1 0 1 
ccc 1 1 1 
ddd 1 1 0 

require(vegan) 
d <- vegdist(x, method="jaccard") 

La distancia la matriz d se obtiene de la siguiente manera:

  aaa  bbb  ccc 
bbb 1.0000000      
ccc 0.6666667 0.3333333   
ddd 0.5000000 0.6666667 0.3333333 

Al escribir str (d), encontré que no es una tabla normal e ni formato csv.

Class 'dist' atomic [1:6] 1 0.667 0.5 0.333 0.667 ... 
    ..- attr(*, "Size")= int 4 
    ..- attr(*, "Labels")= chr [1:4] "aaa" "bbb" "ccc" "ddd" 
    ..- attr(*, "Diag")= logi FALSE 
    ..- attr(*, "Upper")= logi FALSE 
    ..- attr(*, "method")= chr "jaccard" 
    ..- attr(*, "call")= language vegdist(x = a, method = "jaccard") 

quiero para convertir la matriz de distancia a un 3 columnas con nuevas cabeceras y guardarlo como un archivo csv de la siguiente manera:

c1 c2 distance 
aaa bbb 1.000 
aaa ccc 0.6666667 
aaa ddd 0.5 
bbb ccc 0.3333333 
bbb ddd 0.6666667 
ccc ddd 0.3333333 
+5

Esta es una Q de mejor calidad que muchas de las que ha publicado recientemente. Un par de puntos: i) lo que usted llama una tabla es un marco de datos en R. Una tabla en R es otra cosa. ii) Por favor, cuando pueda, vuelva a revisar su Q y acepte respuestas donde aún no lo haya hecho. iii) Responda a los comentarios que los usuarios publican en su Qs. Se supone que no se trata de tráfico unidireccional que usted pide, nosotros proporcionamos respuestas. –

Respuesta

18

se puede hacer esto mediante la combinación de fusión del paquete de cambio de forma, superior .tri etc .:

> library(reshape) 
> m <- as.matrix(d) 
> m 
      aaa  bbb  ccc  ddd 
aaa 0.0000000 1.0000000 0.6666667 0.5000000 
bbb 1.0000000 0.0000000 0.3333333 0.6666667 
ccc 0.6666667 0.3333333 0.0000000 0.3333333 
ddd 0.5000000 0.6666667 0.3333333 0.0000000 
> m2 <- melt(m)[melt(upper.tri(m))$value,] 
> names(m2) <- c("c1", "c2", "distance") 
> m2 
    c1 c2 distance 
5 aaa bbb 1.0000000 
9 aaa ccc 0.6666667 
10 bbb ccc 0.3333333 
13 aaa ddd 0.5000000 
14 bbb ddd 0.6666667 
15 ccc ddd 0.3333333 
26

Esto es bastante factible utilizando las funciones de base R. Primero queremos que todas las combinaciones de pares de las filas llenen las columnas c1 y c2 en el objeto resultante. La columna final distance se logra simplemente convirtiendo el objeto "dist"d en un vector numérico (ya es un vector pero de una clase diferente).

El primer paso se realiza utilizando combn(rownames(x), 2) y el segundo paso a través as.numeric(d):

m <- data.frame(t(combn(rownames(x),2)), as.numeric(d)) 
names(m) <- c("c1", "c2", "distance") 

cual da:

> m 
    c1 c2 distance 
1 aaa bbb 1.0000000 
2 aaa ccc 0.6666667 
3 aaa ddd 0.5000000 
4 bbb ccc 0.3333333 
5 bbb ddd 0.6666667 
6 ccc ddd 0.3333333 

Para guardar como un archivo CSV, write.csv(m, file = "filename.csv").

+1

... y ¿cómo se puede volver a convertir a la clase original (dist)? – theforestecologist

+0

Tengo curiosidad por el revés también. Encontré a este chico proporcionando una solución a través de la remodelación: http://stackoverflow.com/questions/2126108/convert-table-into-matrix-by-column-names –

+0

@MarcoVirgolin Mira la función 'acast()' en el paquete * reshape2 * para una forma de ir al formato ancho (es decir, matriz de distancia completa), entonces us 'as.dist()' para convertir esa matriz en un objeto dist. –

Cuestiones relacionadas