r - 如何在 r 中按最近距离合并两个数据集?

标签 r algorithm merge dataset

我有两个包含值和坐标的数据集 A 和 B

答:

╔═══╦════════════╦═════════════╦═════════════╗
║   ║ name       ║ x           ║ y           ║
╠═══╬════════════╬═════════════╬═════════════╣
║ 1 ║ city       ║ 50.3        ║ 4.2         ║
║ 2 ║ farm       ║ 14.8        ║ 8.6         ║
║ 3 ║ lake       ║ 18.7        ║ 9.8         ║
║ 3 ║ Mountain   ║ 44          ║ 9.8         ║
╚═══╩════════════╩═════════════╩═════════════╝

乙:

╔═══╦════════════╦═════════════╦═════════════╗
║   ║ Temp       ║ x           ║ y           ║
╠═══╬════════════╬═════════════╬═════════════╣
║ 1 ║ 18         ║ 50.7        ║ 6.2         ║
║ 2 ║ 17,3       ║ 20          ║ 11          ║
║ 3 ║ 15         ║ 15          ║ 9           ║
╚═══╩════════════╩═════════════╩═════════════╝

我想要这个,C:

╔═══╦════════════╦═════════════╦═════════════╗
║   ║ Name       ║ Temp        ║ Distance    ║
╠═══╬════════════╬═════════════╬═════════════╣
║ 1 ║ city       ║ 18          ║ 2.039608    ║
║ 2 ║ farm       ║ 15          ║ 0.447214    ║
║ 3 ║ lake       ║ 17.3        ║ 1.769181    ║
║ 4 ║ Mountain   ║ 18          ║ 7.605919    ║
╚═══╩════════════╩═════════════╩═════════════╝

我试过这个:

A<- read.table(header = TRUE, text = "
    Name x y 
    city 50.3 4.2
    farm 14.8 8.6
    lake 18.7 9.8
    mountain 44 9.8")
B<- read.table(header = TRUE, text = "
    Temp x y 
    18 50.7 6.2
    17.3 20 11
    15 15 9")
C<- data.frame(Name=character(),
               Temp=numeric(),
               Distance=numeric())

for(i in 1:nrow(A)) {
  x1<- A[i,]$x
  y1<- A[i,]$y
  min = 100
  index = 0
  for(j in 1:nrow(B)) {
    x2<- B[j,]$x
    y2<- B[j,]$y
    tmp = sqrt((((x2-x1)^2)+((y2-y1)^2)))
    if (tmp < min) {
      index = j
      min = tmp
    }
  }
  df <- list(Name=A[i,]$Name, Temp=B[index,]$Temp, Distance=min)
  C <- rbind(C, df)
}
print(C)

但是我的第一个数据集大约有 1,500,000 行,而我的第二个数据集大约有 5000 行,而且这个算法非常非常慢。有更好的方法吗?

最佳答案

如果你想在 R 中进行hack,你可以使用 R 的 outer 函数(以及 R 擅长 vectorization 的意识)来有效地产生距离A[, c(x,y)]中的所有B[, c(x,y)]中的所有,即得到一个距离矩阵A(行)中的位置来自 B(列)中的每个位置,例如,

A<- read.table(header = TRUE, text = "
               Name x y 
               city 50.3 4.2
               farm 14.8 8.6
               lake 18.7 9.8
               mountain 44 9.8")
B<- read.table(header = TRUE, text = "
               Temp x y 
               18 50.7 6.2
               17.3 20 11
               15 15 9
               18 ")
d <- sqrt(outer(A$x, B$x, "-")^2 + outer(A$y, B$y, "-")^2)
d

##          [,1]      [,2]       [,3]
## [1,]  2.039608 31.053663 35.6248509
## [2,] 35.980133  5.727128  0.4472136
## [3,] 32.201863  1.769181  3.7854986
## [4,]  7.605919 24.029981 29.0110324

接下来可以efficiently通过 matrixStats 包中的 rowMins 方法获取它的值

minD <- matrixStats::rowMins(d)

并假设 B 中有一个唯一的最近位置,通过(按行)将 dminD 进行比较来获取其索引

ind <- (d == minD) %*% 1:ncol(d)

如果 B 中有多个距离相等的位置,您无论如何都需要某种规则来选择。 最后,将数据堆叠在一起。

C <- data.frame(Name = A$Name,
                Temp = B$Temp[ind],
                Distance = minD)

关于r - 如何在 r 中按最近距离合并两个数据集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48152399/

相关文章:

r - 反转累积总和的功能方法?

r - 在 R 中创建一组长度递减的序列

algorithm - 具有两个唯一列的最大行子集

git merge : Removing files I want to keep!

git - .gitattributes 文件应该在提交中吗?

git - 使用 git 对整个文件进行 'accept theirs' 或 'accept mine' 的简单工具

r - Plotly (R) - 饼图 : How to fixate the color assignment color per group?

R:将过滤条件列表传递到数据框中

java - 如何计算确定在某一点结束的无限循环的时间复杂度?

algorithm - 75% 的时间打印 true 的函数