R 使用子集()的循环的矢量化

R 使用子集()的循环的矢量化,r,optimization,loops,R,Optimization,Loops,对于数据帧中的每个点(x,y),我想计算从该点到数据帧中没有相同“组”标签的所有其他点的欧氏距离之和。以下是我试图实现的hacky for loop版本: # some fake data d <- data.frame(group=rep(c('a','b','c'),each=3), x=sample(1:9), y=sample(1:9), z=NA) for (i in 1:nrow(d)) { d2 <- subset(d,group!=d$group[i]) d$

对于数据帧中的每个点(x,y),我想计算从该点到数据帧中没有相同“组”标签的所有其他点的欧氏距离之和。以下是我试图实现的hacky for loop版本:

# some fake data
d <- data.frame(group=rep(c('a','b','c'),each=3), x=sample(1:9), y=sample(1:9), z=NA)
for (i in 1:nrow(d)) {
  d2 <- subset(d,group!=d$group[i])
  d$z[i] <- sum(sqrt((d$x[i]-d2$x)^2 + (d$y[i]-d2$y)^2))
} 
#一些虚假数据

有一个非常好的方法可以有效地解决这个问题:预先计算所有距离并将它们子集,而不是点,以避免重复相同的计算

dists <- as.matrix(dist(d[2:3]))
d$z <- sapply(seq(d$group), function(i) sum(dists[i, !d$group %in% d$group[i]]))

dists有一个非常好的方法可以有效地解决这个问题:预先计算所有距离并将其子集,而不是点,以避免重复相同的计算

dists <- as.matrix(dist(d[2:3]))
d$z <- sapply(seq(d$group), function(i) sum(dists[i, !d$group %in% d$group[i]]))

dists对Backlin的解决方案与loop进行基准测试的结果(使样本数据稍微大一点以扩大差异):


d对Backlin的解决方案与loop进行基准测试的结果(使样本数据稍微大一点以放大差异):


d+1,通过使用
dist
您还可以使用其他距离度量。效率的很大一部分可能来自这样一个事实,即计算是用C完成的。我同意
dist()
的优点,尽管我在我的问题中特别没有使用它,因为我使用的实际公式比简单的欧几里德距离更复杂,需要手动拼写。+1,通过使用
dist
您还可以使用其他距离度量。效率的很大一部分可能来自这样一个事实:计算是用C语言完成的。我同意
dist()的优点
尽管我在我的问题中明确没有使用它,因为我使用的实际公式比简单的欧几里德距离更复杂,需要手动拼写。也许你可以根据@Backlin的答案对你的
循环解决方案进行基准测试?在下面的单独答案中添加基准测试。也许你可以对你的答案进行基准测试
对于
针对@Backlin的答案循环解决方案?在下面的单独答案中添加了基准测试。+1用于进行努力,尽管将其作为编辑添加到您的问题中更常见,或者作为编辑添加到回答中更不常见。+1用于进行努力,尽管将其作为编辑添加到您的问题中更常见,或不太常见的答案编辑。