R语言实现可自定义邻居数的欧氏距离最近邻算法(排除自身)
解决R代码中最近邻排除自身及保留邻居数量灵活性的问题
你的代码核心问题在于排除样本自身的逻辑不够稳健,下面直接给你修正后的代码,并解释关键改动:
修正后的完整代码
data(iris) iris_subset <- iris[, c("Sepal.Length", "Sepal.Width", "Petal.Length")] find_closest_species <- function(flower_row, all_data, row_index, num_closest = 1) { # 计算欧氏距离 distances <- sqrt(rowSums((t(t(all_data) - flower_row))^2)) # 将当前样本自身的距离设为无穷大,确保排序后不会被选中 distances[row_index] <- Inf # 按距离排序并获取索引 sorted_distances <- sort(distances, index.return = TRUE) # 直接取前num_closest个索引,无需额外过滤 closest_indices <- sorted_distances$ix[1:num_closest] iris$Species[closest_indices] } # 应用函数到每一行,保留邻居数量的灵活性 iris$closest_species <- apply(iris_subset, 1, function(row, idx) { paste(find_closest_species(row, iris_subset, idx, num_closest = 1), collapse = ", ") }, idx = seq_len(nrow(iris)))
关键改动说明
- 排除自身样本:在计算完所有距离后,把当前行对应的距离设为
Inf(无穷大),这样排序时它会被放到最后,彻底避免被选为最近邻,比原代码的索引过滤更稳健,不会出现边界情况(比如当num_closest设置较大时,过滤后索引不足的问题)。 - 保留邻居数量灵活性:函数参数
num_closest默认值为1,你可以在调用时随意修改这个值(比如num_closest = 3),就能获取对应数量的最近邻物种,完全保留了灵活性。
验证示例
比如你想获取每个样本的3个最近邻,只需要修改apply里的参数:
iris$closest_species <- apply(iris_subset, 1, function(row, idx) { paste(find_closest_species(row, iris_subset, idx, num_closest = 3), collapse = ", ") }, idx = seq_len(nrow(iris)))
这样就能得到每个样本的3个最近邻物种,且不会包含自身。
内容的提问来源于stack exchange,提问作者Amc
相关产品推荐
相关产品推荐

