isoMDS中的错误(d):对象之间的零距离或负距离

时间:2017-06-23 15:25:48

标签: r multi-dimensional-scaling

我正在尝试使用isoMDS包中的MASS函数执行非度量MDS(R版本3.3.3),我收到此错误:

Error in isoMDS(d): zero or negative distance between objects 1 and 2 

以下是我正在做的一个例子:

# LOAD LIBRARY
library(MASS)

# CREATE FAKE DATA
a <- c(1, 1, 1, 1)
b <- c(2, 2, 2, 2)
c <- c(3, 3, 4, 5)
d <- c(4, 4, 7, 9)
x <- data.frame(a, b, c, d)

x
  a b c d
1 1 2 3 4
2 1 2 3 4
3 1 2 4 7
4 1 2 5 9

# EUCLIDEAN DISTANCE BETWEEN ROWS 1, 2, 3 and 4
d <- dist(x)

d
         1        2        3
2 0.000000                  
3 3.162278 3.162278         
4 5.385165 5.385165 2.236068

# NMDS
fit <- isoMDS(d)

Error in isoMDS(d) : distance négative ou nulle entre les objets 1 et 2

我不知道是否有办法解决这个问题,或者我是否做错了什么。我理解对象1和2是相同的,这可能是距离为负或等于零的原因。我发现我的问题是“常见问题解答”,但我找到的唯一答案之一是:

  

简短回答:你无法比较包括NA在内的距离,所以没有   找到距离的单调映射的方法。如果两行的数据确实相同,则可以轻松删除其中一行   他们在做MDS时,然后将找到的位置分配给   其他

所以,我的下一个问题是:你在做MDS时如何删除行,还有其他方法可以执行NMDS吗?

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:0)

dist函数计算数据矩阵行之间的距离
您的abcd向量是x矩阵的列,而不是行。
一个简单的解决方案是转置x

library(MASS)

a <- c(1, 1, 1, 1)
b <- c(2, 2, 2, 2)
c <- c(3, 3, 4, 5)
d <- c(4, 4, 7, 9)
x <- data.frame(a, b, c, d)

# Calculate distance between the columns
d <- dist(t(x))

# NMDS
fit <- isoMDS(d)

# initial  value 0.000000 
# final  value 0.000000 
# converged

fit
# $points
#        [,1]       [,2]
# a -4.594429  0.4509513
# b -2.770312 -0.3638885
# c  1.098884 -0.3114594
# d  6.265857  0.2243966
# 
# $stress
# [1] 7.976932e-15

我希望它可以帮到你。

答案 1 :(得分:0)

如您所述,您有相同的行。 首次创建距离矩阵时,可以省略相同的行

d <- dist(x[-1,])

然后继续正常

fit <- isoMDS(d)

答案 2 :(得分:0)

或者,您可以尝试使用vegan::metaMDS函数:

library(vegan)
#> This is vegan 2.5-3

x <- data.frame(a = c(1, 1, 1, 1), 
                b = c(2, 2, 2, 2), 
                c = c(3, 3, 4, 5), 
                d = c(4, 4, 7, 9))

# The warnings are expected for such a small dataset
fit <- vegan::metaMDS(comm = dist(x))
#> ... Procrustes: rmse 0.09543314  max resid 0.108719 
#> *** No convergence -- monoMDS stopping criteria:
#>     17: stress < smin
#>      3: scale factor of the gradient < sfgrmin
#> Warning in vegan::metaMDS(comm = dist(x)): stress is (nearly) zero: you may
#> have insufficient data

ordiplot(fit, type = "text")

enter image description here

变量/列“ a”和“ b”(1和2)获得相同的坐标。


类似地,使用smacof::mds函数:

library(smacof)
fit2 <- smacof::mds(delta = dist(x), type = "ordinal")
fit2$conf
#>           D1           D2
#> 1  0.5742535  0.007220978 # 1 & 2 get the same coordinates
#> 2  0.5742535  0.007220978
#> 3 -0.2749314 -0.034928060
#> 4 -0.8735757  0.020486105