4

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

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 吗?

任何帮助将不胜感激!

4

3 回答 3

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

在此处输入图像描述

变量/列“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
于 2018-12-11T16:39:46.250 回答
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

我希望它可以帮助你。

于 2017-06-23T16:07:06.850 回答
0

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

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

然后正常继续

fit <- isoMDS(d)
于 2017-10-08T21:24:00.647 回答