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

时间:2018-01-08 14:32:09

标签: r algorithm merge dataset

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

A:

╔═══╦════════════╦═════════════╦═════════════╗
║   ║ 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         ║
╚═══╩════════════╩═════════════╩═════════════╝

B:

╔═══╦════════════╦═════════════╦═════════════╗
║   ║ 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,这个算法非常慢。有没有更好的方法呢?

1 个答案:

答案 0 :(得分:2)

如果你想在R中使用 hack ,你可以使用R&#39; 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 (行)中位置的距离矩阵}(列)例如,

rowMins

接下来,您可以通过matrixStats包中的minD <- matrixStats::rowMins(d) - 方法efficiently获取其值

B

假设d中有一个唯一的最近位置,则通过minDind <- (d == minD) %*% 1:ncol(d)

的(逐行)比较获取其索引
B

如果C <- data.frame(Name = A$Name, Temp = B$Temp[ind], Distance = minD) 中有多个等距离的位置,那么您无论如何都需要某种规则来选择。 最后,只需将数据堆叠在一起。

entry