首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >dist() foreach结果不一致

dist() foreach结果不一致
EN

Stack Overflow用户
提问于 2020-02-27 13:21:09
回答 1查看 41关注 0票数 0

我的数据大致采用以下格式,但非常大,但使用类和uniqueId变量按组进行分解。其中每个位置是成对的逐行(x,y)。

代码语言:javascript
复制
df <- 
  data.frame(
    x = c(1, 2, 3, 4, 5, 6, 8, 9, 10), 
    y = c(1, 2, 3, 4, 5, 6, 8, 9, 10), 
    class = c(0, 0, 0, 0, 0, 1, 0, 1, 0), 
    uniqueId = c("1-2-3", "1-2-3", "1-2-3", "1-2-4", "1-2-4", "1-2-4", "1-3-2", "1-3-2", "1-3-2"),
    partialId = c("1.2", "1.2", "1.2", "1.2", "1.2", "1.2", "1.3", "1.3", 1.3") 
  )

我使用的函数应该遍历数据帧,并计算到与当前行相同但不同的uniqueId中的另一个对象的最小距离。为了做到这一点,我用下面的方法将我的数据分成块。

代码语言:javascript
复制
indexes <-
  df %>%
  select(partialId) %>%
  unique()

j <- 1

library(doParallel)

class_separation <- c()

cl <- makePSOCKcluster(24)

registerDoParallel(cl)


while(j <= nrow(indexes)) {

  test <- df %>% filter(partialId == indexes$partialId[j])
  n <- nrow(test)
  vec <- numeric(n)
  vec <- foreach(k = 1:n, .combine = 'c', .multicombine = F) %dopar% {
    c(
      min(
        apply(
          test[test$uniqueId == test$uniqueId[k] & test$class != test$class[k], c("x","y")],
          1,
          function(x) dist(rbind(c(test$x[k],test$y[k]), c(x[1], x[2])))
        )
      )
    )
  }
  class_separation <- c(class_separation, vec)
  j <- j + 1
}
endtime <- Sys.time()
stopwatch <- endtime - starttime
closeAllConnections()
registerDoSEQ()
gc()
df <- cbind(df, class_separation)

在处理单次播放或小批量时,此代码似乎运行得很好。然而,在处理完整的数据集时,我得到的结果显然是不正确的。我知道我计算这些距离的方式肯定有缺陷,因为dist()函数本身或%dopar%出错的可能性很小。我已更改为%do%,并且我的结果没有更改。

作为差异的一个示例,下图显示了执行完整数据运行时的class_separation列与我提供给它的一个小示例。正如你所看到的,结果是非常不同的,但我不确定为什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-28 08:02:41

经过一天的思考,问题出在我如何将我的df发送到dist()。

例如,如果我们打算通过

代码语言:javascript
复制
dist(rbind(c(1, 1), c(6, 6)))

dist(rbind(c(1, 1), c(9, 9)))

我们实际传递的是dist(rbind(c(1, 1), c(6, 6, 9, 9)))

这显然不是我想要的。我需要两个距离,然后选择它们之间的最小值或添加其他条件。我发现实现此目的的方法是使用rdist包。

代码语言:javascript
复制
foreach(i = 1:nrow(df), .combine = 'c', .multicombine = F, .packages = c('tidyverse', 
  'rdist')) %dopar% {
    min(
      cdist(
        df[df$class != df$class[i] & df$uniqueId == df$uniqueId[i], ] %>% select(x, y), 
        df %>% select(x, y) %>% slice(i)
      )
    )
}

对于我们的测试数据,这将返回向量

信息2.828427 1.414214 1.414214 1.414214

这正是我想要的。uniqueId没有类== 1选项的前三个条目应该返回Inf,行4到行6的距离是行5的两倍,而所有行都具有相同的uniqueId,而行9到行8和行10的距离相等。我将测试此解决方案是否足够快。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60426700

复制
相关文章

相似问题

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