如何在R语言中计算单列元素对距离?LP范数问题及多列扩展需求
单列元素对LP范数计算修正
原代码的核心问题
- 循环中
lp1被持续覆盖,最终仅输出每个i对应的最后一组元素对的结果,而非所有i<j的元素对计算值 - 未存储所有元素对的结果,仅打印了局部循环的最终值
- 标量计算时
sum属于冗余操作(不影响结果,但可简化函数)
修正后的实现
先简化LP范数函数(针对标量输入优化):
lp_norm <- function(x, y, p) { abs(x - y)^(1/p) }
方法1:保留循环逻辑的修正
a <- c(23,41,32,58,26,77,45,67,23,78,22,9,20) lp_results <- list() for (i in 1:length(a)) { for (j in (i+1):length(a)) { res <- lp_norm(a[i], a[j], p=1) lp_results[[length(lp_results)+1]] <- data.frame(pair_i = a[i], pair_j = a[j], lp1 = res) } } # 转为数据框查看 lp_df <- do.call(rbind, lp_results) print(lp_df)
方法2:向量化实现(更高效)
用expand.grid生成所有i<j的索引对,避免嵌套循环:
a <- c(23,41,32,58,26,77,45,67,23,78,22,9,20) # 生成所有索引对并筛选i<j的情况 idx_pairs <- expand.grid(i = seq_along(a), j = seq_along(a)) |> subset(i < j) # 批量计算LP范数 idx_pairs$lp1 <- mapply(lp_norm, a[idx_pairs$i], a[idx_pairs$j], p=1) # 添加元素值列(可选) idx_pairs$val_i <- a[idx_pairs$i] idx_pairs$val_j <- a[idx_pairs$j] print(idx_pairs)
批量应用到数据框的10列
假设你的数据框名为my_df,可以用lapply遍历每一列,复用上述向量化逻辑:
定义列处理函数
process_col <- function(col, p=1) { idx_pairs <- expand.grid(i = seq_along(col), j = seq_along(col)) |> subset(i < j) idx_pairs$lp_norm <- mapply(lp_norm, col[idx_pairs$i], col[idx_pairs$j], p=p) idx_pairs$val_i <- col[idx_pairs$i] idx_pairs$val_j <- col[idx_pairs$j] return(idx_pairs) }
批量处理所有列
# 得到一个列表,每个元素对应一列的计算结果 col_results <- lapply(my_df, process_col, p=1) # 合并为单个数据框(带原始列标识) all_results <- do.call(rbind, lapply(names(col_results), function(col_name) { df <- col_results[[col_name]] df$original_column <- col_name df })) print(all_results)
内容的提问来源于stack exchange,提问作者mjrf hh
相关产品推荐
相关产品推荐

