1

特定の長方形内にある一連の xy 座標の割合を決定する必要があります。この長方形は、辺が座標系の端から所定の距離だけ離れた領域として定義されます (この場合、座標系は (-50, -20)、(-50, 20)、(50, 20) で囲まれています) ), (50, -20). また、エッジからさまざまな距離の長方形で結果をテストできるようにしたい. 私の方法は次のとおりです:

  # set initial limits to the coordinate system
  lim.xleft = -50
  lim.xright = 50
  lim.ybottom = -20
  lim.ytop = 20

frac.near.edge <- function(coord.pairs, tolerance){
  # set the coordinates of the rectangle of interest
  exclude.xleft = lim.xleft + tolerance
  exclude.xright = lim.xright - tolerance
  exclude.ybottom = lim.ybottom + tolerance
  exclude.ytop = lim.ytop - tolerance
  out <- vector()
  # loop through the pairs testing whether the point is inside the rectangle or outside
  for(i in 1:nrow(coord.pairs)){
    if(coord.pairs[i, 1] > exclude.xleft & coord.pairs[i, 1] < exclude.xright &  coord.pairs[i, 2] > exclude.ybottom & coord.pairs[i, 2] < exclude.ytop){
      out[i] <- "in"
    } else {
      out[i] <- "out"
    }
  }
  # return how many points were inside the rectangle and how many were outside
  return(table(out))
}

# try it out on something much bigger!
foo <- data.fram(x = runif(100), y = runif(100))
system.time(frac.near.edge(foo,  tolerance = 5))

これは、大規模なデータセットの場合は非常に遅くなります (私のデータセットには 10^5 の xy ペアが含まれています)。どうすれば高速化できますか?ループを回避する方法はありますか?

4

2 に答える 2

1
exclude.xleft = lim.xleft + tolerance
exclude.xright = lim.xright - tolerance
exclude.ybottom = lim.ybottom + tolerance
exclude.ytop = lim.ytop - tolerance
out <- c("out", "in")[1+( findInterval(coord.pairs[ , 1], c(exclude.xleft, exclude.xright))==1 &
                       findInterval(coord.pairs[ , 2], c(exclude.ybottom,   exclude.ytop))==1)]

50K のテスト ケースでのメソッドの 19 秒に対して 0.01 秒かかります。

coord.pairs<- cbind(rnorm(50000, 0,50), rnorm(1000,0,20)); tolerance=10
于 2012-04-30T21:29:54.347 に答える
1

これはおそらく SE Code Review ( https://codereview.stackexchange.com/questions/tagged/r )に適しています。このコーディングが役立つかどうかはわかりませんが、質問はプログラミングに関するものではなく、コードの改善に関するものです。また、すべてのデータセットが応答を生成するため、より良いデータセットを生成しました。

foo <- data.frame(x = sample(-100:100, 100, replace=TRUE), 
    y = sample(-100:100, 100, replace=TRUE))

xleft = -50
xright = 50
ybottom = -2
ytop = 20
foo$x >= xleft & foo$x <= xright  & foo$y >= ybottom & foo$y <= ytop 
于 2012-04-30T21:17:34.437 に答える