将数据帧转换为“类”的对象;dist";没有实际计算R中的距离

将数据帧转换为“类”的对象;dist";没有实际计算R中的距离,r,distance,R,Distance,我有一个带有距离的数据帧 df<-data.frame(site.x=c("A","A","A","B","B","C"), site.y=c("B","C","D","C","D","D"),Distance=c(67,57,64,60,67,60)) df?as.dist()应该对您有所帮助,尽管它需要一个矩阵作为输入。不久前,我遇到了一个类似的问题,并这样解决了它: n <- max(table(df$site.x)) + 1 # +1, so we have di

我有一个带有距离的数据帧

df<-data.frame(site.x=c("A","A","A","B","B","C"),   
site.y=c("B","C","D","C","D","D"),Distance=c(67,57,64,60,67,60))

df
?as.dist()
应该对您有所帮助,尽管它需要一个矩阵作为输入。

不久前,我遇到了一个类似的问题,并这样解决了它:

n <- max(table(df$site.x)) + 1  # +1,  so we have diagonal of 
res <- lapply(with(df, split(Distance, df$site.x)), function(x) c(rep(NA, n - length(x)), x))
res <- do.call("rbind", res)
res <- rbind(res, rep(NA, n))
res <- as.dist(t(res))

n没有什么可以阻止您自己创建dist对象。它只是一个距离向量,带有设置标签、大小等属性

使用您的
df
,这就是

dij2 <- with(df, Distance)
nams <- with(df, unique(c(as.character(site.x), as.character(site.y))))
attributes(dij2) <- with(df, list(Size = length(nams),
                                  Labels = nams,
                                  Diag = FALSE,
                                  Upper = FALSE,
                                  method = "user"))
class(dij2) <- "dist"
这些建议包括:

> df
  site.x site.y Distance
1      A      B       67
2      A      C       57
3      A      D       64
4      B      C       60
5      B      D       67
6      C      D       60
> dij2
   A  B  C
B 67      
C 57 60   
D 64 67 60
> dij3
   A  B  C
B 67      
C 57 60   
D 64 67 60

注意:以上内容不检查数据顺序是否正确。确保
df
中的数据顺序与示例中相同;i、 e.在运行我显示的代码之前,先按
site.x
排序,然后再按
site.y
排序。

对于从谷歌进来的人。。。对于这类内容,Reforme2库中的acast函数要简单得多

library(reshape2)
acast(df, site.x ~ site.y, value.var='Distance', fun.aggregate = sum, margins=FALSE)

是的,这就是问题所在。我已经用自己的函数计算了距离。但是,创建树状图或进行PCA等需要距离对象。您必须使用获得的解决方案将data.frame转换为矩阵,然后使用
as.dist
(您只需要矩阵的下三角)请仔细阅读帮助页面,了解类dist的对象实际上是什么。这是非常好的解决方案,谢谢!只有一个问题。为什么最后一行标签会被删除?是否存在可以避免的情况?再次感谢您,这种很好的方法的一个问题是,您必须创建完整的距离矩阵来创建
“dist”
对象。这有点浪费,
rbind()
ing大型数据集可能会很慢。由于您已经有了距离向量,并且类对象只是带有属性的向量,因此直接向距离向量添加属性更容易、更有效。有关示例和详细信息,请参见下面的答案。
library(reshape2)
acast(df, site.x ~ site.y, value.var='Distance', fun.aggregate = sum, margins=FALSE)