2012-05-22 21 views
6

Dada la matriz¿Cómo puedo crear una matriz de distancia que contenga las puntuaciones medias absolutas entre cada fila?

 X1 X2 X3 X4 X5 
[1,] 1 2 3 2 1 
[2,] 2 3 4 4 3 
[3,] 3 4 4 6 2 
[4,] 4 5 5 5 4 
[5,] 2 3 3 3 6 
[6,] 5 6 2 8 4 

Quiero crear una matriz de distancia que contiene la diferencia media absoluta entre cada fila de cada columna. Por ejemplo, la distancia entre X1 y X3 debe ser = 1.67 dado que:

abs (1 - 3) + abs (2-4) + abs (3-4) + abs (4-5) + abs (2-3) + abs (5-2) = 10/6 = 1.67.

He intentado usar la función designdist en el paquete vegan de esta manera:

designdist(t(test), method = "abs(A-B)/6", terms = "minimum") 

La distancia resultante para las columnas 1 y 3 es 0,666. El problema con esta función es que suma todos los valores en cada columna y luego los resta. Pero necesito sumar las diferencias absolutas entre cada fila (individualmente, absoluta) y luego dividirla por N.

Respuesta

5

Aquí hay una solución de una línea. Aprovecha el argumento dist() de method para calcular el L1 norm aka city block distance aka Manhattan distance entre cada par de columnas en su data.frame.

as.matrix(dist(df, "manhattan", diag=TRUE, upper=TRUE)/nrow(df)) 

Para que sea reproducible:

df <- read.table(text=" 
X1 X2 X3 X4 X5 
    1 2 3 2 1 
    2 3 4 4 3 
    3 4 4 6 2 
    4 5 5 5 4 
    2 3 3 3 6 
    5 6 2 8 4", header=T) 

dmat <- as.matrix(dist(df, "manhattan", diag=TRUE, upper=TRUE)/nrow(df)) 
print(dmat, digits=3) 
#  1  2  3 4  5 6 
# 1 0.00 1.167 1.667 2.33 1.333 3.00 
# 2 1.17 0.000 0.833 1.17 0.833 2.17 
# 3 1.67 0.833 0.000 1.00 1.667 1.67 
# 4 2.33 1.167 1.000 0.00 1.667 1.33 
# 5 1.33 0.833 1.667 1.67 0.000 2.33 
# 6 3.00 2.167 1.667 1.33 2.333 0.00 
+0

funcionó muy bien! ¡Gracias! – Werner

Cuestiones relacionadas