我正在尝试使用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吗?
非常感谢任何帮助!
答案 0 :(得分:0)
dist
函数计算数据矩阵行之间的距离。
您的a
,b
,c
和d
向量是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")
变量/列“ 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