我创建了一个点的2D地图
set.seed(3000)
Citysize <-1000
Range <- 0.05
vertical<-rnorm(Citysize,0,1)
horizontal<-rnorm(Citysize,0,1)
Map <-as.data.frame(cbind(vertical,horizontal))
plot(Map)
其中一些点是特殊的
special <- runif(Citysize,0,1)
Map <-as.data.frame(cbind(vertical,horizontal,special))
Map$special[Map$special >0.8] <- 1
Map$special[Map$special <0.8] <- 0
每个点都是一个正方形的中心,我想知道这个正方形内有多少个点。
Map$v1 <- Map$vertical - Range
Map$v2 <- Map$vertical + Range
Map$h1 <- Map$horizontal - Range
Map$h2 <- Map$horizontal + Range
我试过了
apply(Map, 1, function(x) length(which(x[1]>Map[4]& x[1]<Map[5])))
仅适用于1个条件(垂直),但我不知道如何包含其他条件。有什么建议吗?
答案 0 :(得分:0)
您可以使用vertical
和horizontal
介于v1/v2
和h1/h2
之间的条件将数据加入到自身中。在这种情况下,我使用data.table
,但您可以使用任何支持非equi连接的其他内容(如sqldf
)。从我对你的问题的理解,我忽略了&#34;特殊的点&#34;因为您提供的示例代码似乎没有考虑到它们。
res <- setDT(Map)[Map, .(i.vertical, i.horizontal, i.v1, i.v2, i.h1, i.h2, x.vertical, x.horizontal),
on=.( vertical >= v1, vertical <= v2, horizontal >= h1, horizontal <= h2)]
res2 <- res[, .(count = .N - 1), by = .(i.vertical, i.horizontal, i.v1, i.v2, i.h1, i.h2)]
head(res2)
# i.vertical i.horizontal i.v1 i.v2 i.h1 i.h2 count
#1: 1.2582925 0.5991733 1.2082925 1.3082925 0.5491733 0.6491733 1
#2: 0.6447519 -0.9258515 0.5947519 0.6947519 -0.9758515 -0.8758515 2
#3: 0.4633460 -2.0512540 0.4133460 0.5133460 -2.1012540 -2.0012540 0
#4: 0.7703058 0.2609452 0.7203058 0.8203058 0.2109452 0.3109452 0
#5: -0.2263347 -0.7152786 -0.2763347 -0.1763347 -0.7652786 -0.6652786 0
#6: -0.3515479 0.4835811 -0.4015479 -0.3015479 0.4335811 0.5335811 0
注意我从组的长度中减去了一个因为它与自身的观察匹配所以我们需要排除它。
答案 1 :(得分:0)
在我看来,这个解决方案很丑陋,可能会做得更好,但至少它会遵循你的语法。我将Map$special
更改为逻辑向量,并在&#34;之间使用了%b%
&#34;功能,因为我觉得它很容易阅读。
## is lhs between (strict) rhs? (Vectorized)
`%b%` <- function(x,rng) min(rng) < x & x < max(rng)
## Horizontal and vertical values of special points
specialh <- Map$horizontal[Map$special]
specialv <- Map$vertical[Map$special]
## For each special point check if Map point is in range
sapply(1:length(specialh), function(i){
h <- Map$horizontal %b% c(specialh[i] + Range * c(-1,1))
v <- Map$vertical %b% c(specialv[i] + Range * c(-1,1))
## Subtract 1 because otherwise we count the point itself
sum(h&v) - 1
})
# [1] 0 2 0 0 3 0 0 0 0 1 0 2 1 0 0 3 0 0 2 0 0 2 1 1 2 0 0
# [28] 1 0 0 1 1 0 0 1 0 3 1 1 1 0 0 2 1 1 4 1 0 0 1 0 0 0 3
# [55] 0 0 0 1 1 0 2 2 0 2 0 1 2 0 0 0 0 2 1 0 1 0 0 1 0 3 1
# [82] 0 1 0 1 2 2 0 2 1 0 0 1 0 0 0 0 0 3 2 2 1 1 0 0 0 0 0
# [109] 0 0 2 0 0 0 2 0 0 1 0 1 0 1 1 2 1 3 0 0 0 0 0 1 0 0 2
# [136] 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 2 0 0 3 0 0 0 1 0 0 0
# [163] 0 0 2 0 2 0 0 2 0 0 0 1 1 0 0 0 2 0 1 3 1 0 0 0 3 0 0
# [190] 0 3 0 0 0 0 1 2