用于 R 树实现的 R 库
R library for R-tree implementation
我有数据框,例如
df <- data.frame(x = 1:1e3, y = rnorm(1e3))
我需要在 N 个(在我的例子中 N = 6、12 和 24)矩形上拆分具有相同点数的点。如何使用 R-tree algorithm?
拆分我的 df
如果所有点的 x 坐标都不同,如您的示例中的情况,请根据 x 坐标对点进行递增排序。请注意,在这种情况下,您可以简化为 2d 点找到矩形覆盖(具有相同数量的点)的问题,以找到具有 1d 点段的覆盖(即您可以忽略矩形的高度)。
这里是如何找到每个矩形中的点的方法:
num_rect <- 7 # In your example 6, 12 or 24
num_points <- 10 # In your example 1e3
# Already ordered according to x
df <- data.frame(x = 1:num_points, y = rnorm(num_points))
# Minimum number of points in the rectangles to cover all of them
points_in_rect <- ceiling(num_points/num_rect)
# Cover the first points using non-overlaping rectangles
breaks <- seq(0,num_points, by=points_in_rect)
cover <- split(seq(num_points), cut(seq(num_points), breaks))
names(cover) <- paste0("rect", seq(length(cover)))
# Cover the last points using overlaping rectangles
cur_num <- length(cover)
if (num_points < num_rect*points_in_rect ) {
# To avoid duplicate rectangles
last <- num_points
if (num_points %% 1 == 0)
last <- last -1
while (cur_num < num_rect) {
cur_num <- cur_num + 1
new_rect <- list(seq(last-points_in_rect+1, last))
names(new_rect) <- paste0("rect", cur_num)
cover <- c(cover,new_rect)
last <- last - points_in_rect
}
}
矩形中的点是:
$rect1
[1] 1 2
$rect2
[1] 3 4
$rect3
[1] 5 6
$rect4
[1] 7 8
$rect5
[1] 9 10
$rect6
[1] 8 9
$rect7
[1] 6 7
包围这些点集的最小边界矩形(平行于轴)就是您要找到的那些。
两个轴上的重复坐标值
随机旋转点(保存旋转角度)并检查是否没有重复的x(或y)坐标。如果是这种情况,将上面的策略与旋转后的坐标一起使用(记得在旋转后的点之前根据新的x坐标进行排序),然后将得到的矩形按相反的方向旋转回来。如果重复的坐标保留在两个轴中,请以不同的(随机)角度再次旋转这些点。由于您的点数有限,因此您总能找到一个将 de x(或 y)坐标分开的旋转角度。
对于 x 轴上均匀分布的数据,kmeans
聚类效果很好(毫不奇怪):
library(dplyr)
library(ggplot2)
set.seed(1)
df <- data.frame(x = 1:1e3, y = rnorm(1e3))
N <- 10
df$cluster <- kmeans(df,N)$cluster
cluster_rectangles <- df %>% group_by(cluster) %>%
summarize(xmin = min(x),
xmax = max(x),
ymin = min(y),
ymax = max(y),
n = n())
ggplot() + geom_rect(data = cluster_rectangles, mapping=aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, fill=cluster)) +
geom_point(data = df,mapping=aes(x,y),color='white')
如果 x 分布正常,它也有效:
df <- data.frame(x = rnorm(1e3), y = rnorm(1e3))
缺点是每个矩形的点数不同:
> cluster_rectangles %>% select(cluster,n)
# A tibble: 10 x 2
cluster n
<int> <int>
1 1 137
2 2 58
3 3 121
4 4 61
5 5 72
6 6 184
7 7 78
8 8 70
9 9 126
10 10 93
对于均匀分布,结果很好(N=9):
我有数据框,例如
df <- data.frame(x = 1:1e3, y = rnorm(1e3))
我需要在 N 个(在我的例子中 N = 6、12 和 24)矩形上拆分具有相同点数的点。如何使用 R-tree algorithm?
拆分我的 df如果所有点的 x 坐标都不同,如您的示例中的情况,请根据 x 坐标对点进行递增排序。请注意,在这种情况下,您可以简化为 2d 点找到矩形覆盖(具有相同数量的点)的问题,以找到具有 1d 点段的覆盖(即您可以忽略矩形的高度)。
这里是如何找到每个矩形中的点的方法:
num_rect <- 7 # In your example 6, 12 or 24
num_points <- 10 # In your example 1e3
# Already ordered according to x
df <- data.frame(x = 1:num_points, y = rnorm(num_points))
# Minimum number of points in the rectangles to cover all of them
points_in_rect <- ceiling(num_points/num_rect)
# Cover the first points using non-overlaping rectangles
breaks <- seq(0,num_points, by=points_in_rect)
cover <- split(seq(num_points), cut(seq(num_points), breaks))
names(cover) <- paste0("rect", seq(length(cover)))
# Cover the last points using overlaping rectangles
cur_num <- length(cover)
if (num_points < num_rect*points_in_rect ) {
# To avoid duplicate rectangles
last <- num_points
if (num_points %% 1 == 0)
last <- last -1
while (cur_num < num_rect) {
cur_num <- cur_num + 1
new_rect <- list(seq(last-points_in_rect+1, last))
names(new_rect) <- paste0("rect", cur_num)
cover <- c(cover,new_rect)
last <- last - points_in_rect
}
}
矩形中的点是:
$rect1
[1] 1 2
$rect2
[1] 3 4
$rect3
[1] 5 6
$rect4
[1] 7 8
$rect5
[1] 9 10
$rect6
[1] 8 9
$rect7
[1] 6 7
包围这些点集的最小边界矩形(平行于轴)就是您要找到的那些。
两个轴上的重复坐标值
随机旋转点(保存旋转角度)并检查是否没有重复的x(或y)坐标。如果是这种情况,将上面的策略与旋转后的坐标一起使用(记得在旋转后的点之前根据新的x坐标进行排序),然后将得到的矩形按相反的方向旋转回来。如果重复的坐标保留在两个轴中,请以不同的(随机)角度再次旋转这些点。由于您的点数有限,因此您总能找到一个将 de x(或 y)坐标分开的旋转角度。
对于 x 轴上均匀分布的数据,kmeans
聚类效果很好(毫不奇怪):
library(dplyr)
library(ggplot2)
set.seed(1)
df <- data.frame(x = 1:1e3, y = rnorm(1e3))
N <- 10
df$cluster <- kmeans(df,N)$cluster
cluster_rectangles <- df %>% group_by(cluster) %>%
summarize(xmin = min(x),
xmax = max(x),
ymin = min(y),
ymax = max(y),
n = n())
ggplot() + geom_rect(data = cluster_rectangles, mapping=aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, fill=cluster)) +
geom_point(data = df,mapping=aes(x,y),color='white')
df <- data.frame(x = rnorm(1e3), y = rnorm(1e3))
> cluster_rectangles %>% select(cluster,n)
# A tibble: 10 x 2
cluster n
<int> <int>
1 1 137
2 2 58
3 3 121
4 4 61
5 5 72
6 6 184
7 7 78
8 8 70
9 9 126
10 10 93
对于均匀分布,结果很好(N=9):