如何为R语言数据集添加基于数值相似度的邻近实体列?
为实体匹配数值最邻近实体的R语言实现
需求说明
我有一组带对应数值的实体列表,需要为每个实体找出列表中数值绝对值差最小的邻近实体。
玩具示例
输入数据:
Lab Val A 0.4 B 0.1 C 0.2
处理后输出:
Lab Val Neigh A 0.4 C B 0.1 C C 0.2 B
实际场景背景
以eurodist数据集为例,已完成如下预处理:
data(eurodist) labs <- labels(eurodist) splt <- split(eurodist, labs) splt_mean <- lapply(splt, mean) x <- as.data.frame(splt_mean) x <- transpose(x) colnames(x) <- "Mean" rownames(x) <- labs
现在需要给数据框x添加Neigh列,存储每个城市对应的数值最接近的邻近城市,已知可通过lapply(splt_mean, ...)实现,但不清楚如何指定其中的FUN函数。
解决方案
步骤1:将均值列表转换为命名向量
先把lapply生成的均值列表转换成命名向量,方便后续计算差值:
mean_vec <- unlist(splt_mean)
步骤2:定义匹配最邻近实体的函数
编写自定义函数,输入单个数值和整个均值向量,返回数值最接近的实体名称(排除自身):
get_nearest_neighbor <- function(current_val, all_vals) { # 计算当前值与所有值的绝对值差 diffs <- abs(all_vals - current_val) # 将自身的差值设为无穷大,避免匹配自己 diffs[names(diffs) == names(current_val)] <- Inf # 返回差值最小的实体名称 names(all_vals)[which.min(diffs)] }
步骤3:应用函数生成Neigh列
使用sapply遍历均值向量,为每个元素匹配最邻近实体,并将结果添加到数据框x中:
x$Neigh <- sapply(mean_vec, get_nearest_neighbor, all_vals = mean_vec)
完整代码整合
把所有步骤整合在一起:
data(eurodist) labs <- labels(eurodist) splt <- split(eurodist, labs) splt_mean <- lapply(splt, mean) x <- as.data.frame(splt_mean) x <- transpose(x) colnames(x) <- "Mean" rownames(x) <- labs # 转换为命名向量 mean_vec <- unlist(splt_mean) # 定义匹配函数 get_nearest_neighbor <- function(current_val, all_vals) { diffs <- abs(all_vals - current_val) diffs[names(diffs) == names(current_val)] <- Inf names(all_vals)[which.min(diffs)] } # 添加Neigh列 x$Neigh <- sapply(mean_vec, get_nearest_neighbor, all_vals = mean_vec)
运行后,数据框x就会包含每个城市对应的最邻近城市列了。
内容的提问来源于stack exchange,提问作者compbiostats
相关产品推荐
相关产品推荐

