【问题标题】:R: Improvement of loop to create distance matrix from data frameR:改进循环以从数据帧创建距离矩阵
【发布时间】:2014-04-11 12:44:10
【问题描述】:

我正在使用 R 中数据框中的数据创建距离矩阵。

我的数据框有 2244 个位置的温度:

plot    temperature
A       12
B       12.5
C       15
...     ...

我想创建一个矩阵来显示每对位置之间的温差:

.   A    B    C
A   0    0.5  3
B   0.5  0    0.5
C   3    2.5  0

这是我在 R 中提出的:

temp_data  #my data frame with the two columns: location and temperature

temp_dist<-matrix(data=NA, nrow=length(temp_data[,1]), ncol=length(temp_data[,1]))
temp_dist<-as.data.frame(temp_dist)
names(temp_dist)<-as.factor(temp_data[,1]) #the locations are numbers in my data
rownames(temp_dist)<-as.factor(temp_data[,1])

for (i in 1:2244)
{
  for (j in 1:2244)
  {
   temp_dist[i,j]<-abs(temp_data[i,2]-temp_data[j,2])
  }
}

我已经用一个小示例尝试了代码:

 for (i in 1:10)

而且效果很好。 我的问题是计算机现在已经运行了整整两天,但还没有完成。

我想知道是否有一种方法可以更快地做到这一点。我知道循环中的循环需要很多次,我试图填充超过 500 万个单元格的矩阵,这需要很长时间是有道理的,但我希望有一个公式可以得到相同的结果更快的时间,因为我必须对降水和其他变量做同样的事情。

我还阅读了有关 dist 的信息,但我不确定是否可以使用我拥有的数据框使用该公式。

非常感谢您的合作。

非常感谢。

【问题讨论】:

  • 您是否在一些示例数据上尝试过dist(temp_data$temperature, method="euclidean", diag=TRUE, upper=TRUE)?我不知道处理大型数据集需要多长时间,但可能值得研究。
  • 它是即时的......对不起这样一个愚蠢的问题,非常感谢您的回答。 @romansegelskyi 这确实是一个类似的问题。

标签: r loops matrix distance


【解决方案1】:

您是否只是在寻找以下内容?

out <- dist(temp_data$temperature, upper=TRUE, diag=TRUE)
out
#     1   2   3
# 1 0.0 0.5 3.0
# 2 0.5 0.0 2.5
# 3 3.0 2.5 0.0

如果您想要不同的行/列名称,看来您必须先将其转换为矩阵:

out_mat <- as.matrix(out)
dimnames(out_mat) <- list(temp_data$plot, temp_data$plot)
out_mat
#     A   B   C
# A 0.0 0.5 3.0
# B 0.5 0.0 2.5
# C 3.0 2.5 0.0

【讨论】:

  • 这个答案确实很有帮助,但我发现了一个问题。 dist() 创建的 dist 对象没有标签,因此我不能将它用于 mantel 测试。
  • 我曾尝试使用labels(dist(temp_data$temperature, upper=TRUE, diag=TRUE))&lt;-temp_data[,1] 遗憾的是这不起作用。我也试过vegdist()。当我使用物种距离时,我得到标签:Class 'dist' atomic [1:2516646] 0.5 0.963 0.412 0.929 0.788 ... ..- attr(*, "Size")= int 2244 ..- attr(*, "Labels")= chr [1:2244] "33013" "35443" "52809" "38917" ... ..- attr(*, "Diag")= logi TRUE ..- attr(*, "Upper")= logi FALSE ..- attr(*, "method")= chr "jaccard" ..- attr(*, "call")= language vegdist(x = species_mat[, 2:248], method = "jaccard", diag = T)
  • @Greta,我猜你正在尝试添加dimnames。查看我的更新。
  • 我想我找到了另一种解决方案。一旦我有了 dist 对象,我就添加了一个新属性 attr(out, "Labels")&lt;-as.factor(temp_data[1:2244,1]) Mantel 测试已经成功地做到了。我不知道您的解决方案是否会起作用,因为mantel() 需要一个 dist 对象。如果我将我的代码添加到您的答案中可以吗?那将是完整的答案。 :)
【解决方案2】:

或者只是作为工具箱的替代品:

m <- with(temp_data, abs(outer(temperature, temperature, "-")))
dimnames(m) <- list(temp_data$plot, temp_data$plot)
m
#     a   b   c
# a 0.0 0.5 3.0
# b 0.5 0.0 2.5
# c 3.0 2.5 0.0

【讨论】:

  • 非常感谢您的建议。我会牢记在心。
  • 这似乎更快。 +1
  • 实际上,我想不会更快,但仍然是一个不错的选择。
  • @AnandaMahto,谢谢!使用 2244 温度,它似乎比您的 dist 慢 3-4 倍。好吧,我突然想到了,我也可以分享一下。
猜你喜欢
  • 1970-01-01
  • 2020-09-11
  • 1970-01-01
  • 2018-06-20
  • 2015-06-11
  • 1970-01-01
  • 2014-04-15
  • 2019-07-13
  • 1970-01-01
相关资源
最近更新 更多