首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向量化使用subset()的for循环

向量化使用subset()的for循环
EN

Stack Overflow用户
提问于 2012-10-01 12:24:46
回答 2查看 117关注 0票数 1

对于数据框中的每个点(x,y),我想计算从该点到数据框中不具有相同“group”标签的所有其他点的欧几里得距离之和。下面是我想要实现的一个简单的for循环版本:

代码语言:javascript
复制
# 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))
} 

例如,点a1的期望值应该是从a1到b1、b2、b3、c1、c2、c3中每一个的距离之和,但不包括距离a1-a2或a1-a3。有没有一种矢量化的方法来实现这一点?我确信这是一个显而易见的解决方案。我尝试了by()apply()的各种配置,但似乎找不到答案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-01 14:43:47

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

代码语言:javascript
复制
dists <- as.matrix(dist(d[2:3]))
d$z <- sapply(seq(d$group), function(i) sum(dists[i, !d$group %in% d$group[i]]))
票数 3
EN

Stack Overflow用户

发布于 2012-10-02 00:17:53

对Backlin的解决方案vs循环进行基准测试的结果(使样本数据更大,以放大差异):

代码语言:javascript
复制
d <- data.frame(group=rep(letters[1:10],each=100), x=sample(1:1000), y=sample(1:1000), z=NA)
loopMethod <- function(d) {
  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))
  }
}
backlinMethod <- function(d) {
  dists <- as.matrix(dist(d[2:3]))
  d$z <- sapply(seq(d$group), function(i) sum(dists[i, !d$group %in% d$group[i]]))
}
system.time(loopMethod(d))
 user  system elapsed 
1.020   0.004   1.021 
system.time(backlinMethod(d))
 user  system elapsed 
0.472   0.052   0.525 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12667522

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档