base R按行操作问题:使用apply计算两点距离得到异常结果
原代码运行异常原因
apply按行遍历start时,每次仅将start的单行数据传入自定义函数,而你传入的参数y = stop是完整的4行数据框,并未实现逐行配对传入,因此每次函数计算的是start单行与整个stop数据框的运算结果,不符合逐行配对计算的需求。- 你的
start和stop列名不一致,直接对两个数据框的行做减法时,R会优先按列名匹配运算,若你需要按位置对应坐标数值计算距离,建议先提取两个数据框的数值矩阵再运算,避免列名不匹配带来的隐式错误。
base R实现方案
方案1:使用mapply实现逐行配对运算
mapply支持对多个输入对象的对应元素(此处为对应行)配对传入函数运算:
# 自定义距离函数 d <- function(x,y){ length <- norm(x-y,type="2") as.numeric(length) } # 构造测试数据 start <- data.frame( a = c(7, 5, 17, 1), b = c(5, 17, 1, 2)) stop <- data.frame( b = c(5, 17, 1, 2), c = c(17, 1, 2, 1)) # 按行拆分两个数据框为列表 start_row_list <- asplit(start, 1) stop_row_list <- asplit(stop, 1) # 逐行配对计算距离 dist_result <- mapply(d, x = start_row_list, y = stop_row_list)
方案2:向量化运算(效率更高)
由于你计算的是欧氏距离,可以直接通过向量化运算实现,无需使用循环类函数,在数据量较大时性能更优:
# 转成数值矩阵避免列名匹配问题,逐行计算平方和再开方 dist_result <- sqrt(rowSums((as.matrix(start) - as.matrix(stop))^2))
方案3:基于行索引的apply实现
如果要使用apply函数,可以遍历行索引实现配对:
dist_result <- apply(matrix(seq_len(nrow(start)), ncol = 1), 1, function(idx) d(start[idx,], stop[idx,]))
内容的提问来源于stack exchange,提问作者Rafau
相关产品推荐
相关产品推荐

