在 R 中找到最近的行

finding nearest rows with apply in R

我正在尝试使此功能 运行 更快。理想情况下,我只需要 运行 之类的东西应用于数据框,并让它比我目前拥有的更快地吐出结果。该函数的作用是采用如下所示的数据框

df
   Var1 Var2
    5    0
    9    0
    4    1
    6    1
    2    2
    4    2

然后它遍历每一行并检查数据框中其他行中的哪个值最接近(在 Var1 和 Var2 中)您所在行中 Var1 和 Var2 的值。输出然后是一个列表,其中的行最接近每隔一行。例如

myFunc(df)

[[1]]
[1] 3 4

[[2]]
integer(0)

[[3]]
[1] 1 6

[[4]]
[1] 1

[[5]]
integer(0)

[[6]]
[1] 3

所以第 1 行的值最接近第 3 行和第 4 行,而第 2 行附近没有其他行。这是 myFunc

myFunc = function(t) {
x=matrix(); x2=list()
y = matrix(); y2 = list()
for (i in 1:nrow(t)){
    for (j in 1:nrow(t)){
        #this will check for other rows <= 1 from the row I am currently in
        if (abs(t[i,1] - t[j,1]) <= 1) {
            x[j] = j
        } else { x[j] = NA }
        if (abs(t[i,2] - t[j,2]) <= 1) {
            y[j] = j
        } else { y[j] = NA }
    }
    x2[[i]] = x
    y2[[i]] = y
}
for (i in 1:length(x2)){
    x2[[i]] = x2[[i]][!x2[[i]] == i]
    y2[[i]] = y2[[i]][!y2[[i]] == i]
}
x2 = lapply(x2, function(x) x[!is.na(x)])
y2 = lapply(y2, function(x) x[!is.na(x)])

#this intersects Var1 and Var2 to find factors that are close to both Var1 and Var2
z = list()
for (i in 1:length(x2)){
    z[[i]] = intersect(unlist(x2[[i]]), unlist(y2[[i]]))
}
return(z)}

嗯...你有 O(N2) 算法。这样做怎么样:

  • 添加 index/ID 列 df$ID <- seq.int(nrow(df)) (O(N))
  • 使用稳定排序将 dfVar1 排序 (O(N log(N)))
  • 对列进行差分的一次线性传递,构建逻辑向量 (O(N))
  • 从 ID 列获取索引 (O(N))

Var2

相同

然后你可以做结果的交集

假设您只处理两列并且两列都是整数,您可以使用 dist 和欧氏距离计算每个点之间的实际距离。然后你可以过滤那些更大的距离 2^0.5.

如果您使用整数,它会起作用,因为如果 var1 或 var2 中的距离为 2 或更大,您想要丢弃它,但在任何这些情况下,它总是 >= 2

如果您不使用整数,您仍然可以使用 dist 但单独处理每一列然后过滤它们。

我在想:

d1 <- dist(df$Var1) # or d1 <- dist(Var1)
d2 <- dist(df$Var2) # or d2 <- dist(Var2)

现在可以过滤小于1的了

dF <- as.matrix(d1) <= 1 & as.matrix(d2) <= 1
diag(dF) <- NA

要获得最终结果,您可以

colnames(dF) <- NULL
dF2 <- lapply(as.data.frame(dF), which)
names(dF2) <- 1:nrow(df)

# dF2
# $`1`
# [1] 3 4

# $`2`
# integer(0)

# $`3`
# [1] 1 6

# $`4`
# [1] 1

# $`5`
# integer(0)

# $`6`
# [1] 3