R - 根据排名偏好分解覆盖区域数据
R - Disaggregate coverage area data based on a ranking preference
我在英国的地方当局级别拥有 4G 移动覆盖,占所覆盖地理区域的百分比(大约 200 个区域)。我想分解这些数据,以便我可以处理大约 9000 lower-level 个邮政编码扇区。
对我来说最合适的方法是首先将 4G 地理覆盖分配到人口最密集的地区,因为这最能代表移动运营商将如何投资市场。人口最少的地区最终将没有覆盖。但是,我正在为如何在 R 中执行此操作而苦苦挣扎。
我有一个类似这样的邮政编码扇区数据的数据框(我在这里使用了假设数据):
Name pcd.sect pop area pop.dens rank
Cambridge 1 5546 0.6 8341 1
Cambridge 2 7153 1.1 5970 2
Cambridge 3 5621 2.3 5289 3
Cambridge 4 10403 4.3 4361 4
Cambridge 5 14796 4.2 3495 5
...
然后我获取汇总的地方当局数据并将其放在每一行(添加右三列):
Name pcd.sect pop area pop.dens rank LA.4G LA.area LA.4G(km2)
Cambridge 1 5546 0.6 8341 1 58 140 82
Cambridge 2 7153 1.1 5970 2 58 140 82
Cambridge 3 5621 2.3 5289 3 58 140 82
Cambridge 4 10403 4.3 4361 4 58 140 82
Cambridge 5 14796 4.2 3495 5 58 140 82
...
我不得不缩短标题,所以让我更详细地解释一下:
- 名称 - 地方当局名称
- pcd.sector - 邮编区(即下级单位)
- pop - 邮政编码区的人口
- area - 以 km2 为单位的邮政编码扇区的表面积
- pop.dens - 是邮政编码区的人口密度,以每平方公里的人为单位
- rank - 根据每个地方当局的人口密度对邮政编码区段的排名
- LA.4G - 地方当局 4G 覆盖率
- LA.area - 每个地方当局的区域列的总和
- LA.4G(km2) - 每个地方当局内具有 4G 覆盖的 km2 的数量
以剑桥为例,整个地方政府的4G覆盖率为58%。然后我想分解这个数字以实现各个邮政编码区域的 4G 覆盖。
理想情况下,数据最终看起来像这样,并为邮政编码扇区覆盖范围增加一列:
Name pcd.sect ... pcd.sector.coverage (%)
Cambridge 1 ... 100
Cambridge 2 ... 100
Cambridge 3 ... 100
Cambridge 4 ... 34
Cambridge 5 ... 0
... ... ... ...
如何让 R 根据区域列将这 82 平方公里(58% 的地理覆盖范围)分配给新列中的邮政编码扇区,然后在达到 82 平方公里(58%)的最大覆盖水平后停止地理覆盖率百分比)?
这就是我对这个问题的解释。如果这不是你的意思,请纠正我。
假设你有以下数据。
dat <- data.frame(
Name = "A", pcd.sector = 1:5,
area = c(2, 3, 1, 5, 3),
areaSum = 14, LA.4G = 8
)
dat
# Name pcd.sector area areaSum LA.4G
#1 A 1 2 14 8
#2 A 2 3 14 8
#3 A 3 1 14 8
#4 A 4 5 14 8
#5 A 5 3 14 8
你有五个扇区,有不同的区域。虽然加起来有14个,但4G覆盖的只有8个。您想分配扇区 1 到 5 的区域。
以下代码完成这项工作。我使用 cumsum
函数计算顶部扇区的面积累计和,该扇区受 4G 覆盖限制的限制。分配的区域可以通过 diff
函数计算,该函数采用向量的一步差。扇区 1 到 3 获得 100% 的覆盖率,总共有 6 个区域,因此只剩下 2 个。 4区虽然有5区,但只能享受2区,也就是40%。这用完了区域,扇区 5 没有留下任何东西。
dat$area_allocated <- diff(c(0, pmin(cumsum(dat$area), dat$LA.4G)))
dat$area_coverage <- dat$area_allocated / dat$area * 100
dat
# Name pcd.sector area areaSum LA.4G area_allocated area_coverage
# 1 A 1 2 14 8 2 100
# 2 A 2 3 14 8 3 100
# 3 A 3 1 14 8 1 100
# 4 A 4 5 14 8 2 40
# 5 A 5 3 14 8 0 0
如果您有很多区域,那么您可能需要使用 dplyr::group_by
功能。
dat <- rbind(
data.frame(
Name = "A", pcd.sector = 1:5,
area = c(2, 3, 1, 5, 3),
areaSum = 14, LA.4G = 8
),
data.frame(
Name = "B", pcd.sector = 1:3,
area = c(4, 3, 2),
areaSum = 9, LA.4G = 5
)
)
library(dplyr)
dat <- dat %>% group_by(Name) %>%
mutate(area_allocated = diff(c(0, pmin(cumsum(area), LA.4G)))) %>%
mutate(area_coverage = area_allocated / area * 100)
dat
# Name pcd.sector area areaSum LA.4G area_allocated area_coverage
# <fctr> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 A 1 2 14 8 2 100.00000
# 2 A 2 3 14 8 3 100.00000
# 3 A 3 1 14 8 1 100.00000
# 4 A 4 5 14 8 2 40.00000
# 5 A 5 3 14 8 0 0.00000
# 6 B 1 4 9 5 4 100.00000
# 7 B 2 3 9 5 1 33.33333
# 8 B 3 2 9 5 0 0.00000
我在英国的地方当局级别拥有 4G 移动覆盖,占所覆盖地理区域的百分比(大约 200 个区域)。我想分解这些数据,以便我可以处理大约 9000 lower-level 个邮政编码扇区。
对我来说最合适的方法是首先将 4G 地理覆盖分配到人口最密集的地区,因为这最能代表移动运营商将如何投资市场。人口最少的地区最终将没有覆盖。但是,我正在为如何在 R 中执行此操作而苦苦挣扎。
我有一个类似这样的邮政编码扇区数据的数据框(我在这里使用了假设数据):
Name pcd.sect pop area pop.dens rank
Cambridge 1 5546 0.6 8341 1
Cambridge 2 7153 1.1 5970 2
Cambridge 3 5621 2.3 5289 3
Cambridge 4 10403 4.3 4361 4
Cambridge 5 14796 4.2 3495 5
...
然后我获取汇总的地方当局数据并将其放在每一行(添加右三列):
Name pcd.sect pop area pop.dens rank LA.4G LA.area LA.4G(km2)
Cambridge 1 5546 0.6 8341 1 58 140 82
Cambridge 2 7153 1.1 5970 2 58 140 82
Cambridge 3 5621 2.3 5289 3 58 140 82
Cambridge 4 10403 4.3 4361 4 58 140 82
Cambridge 5 14796 4.2 3495 5 58 140 82
...
我不得不缩短标题,所以让我更详细地解释一下:
- 名称 - 地方当局名称
- pcd.sector - 邮编区(即下级单位)
- pop - 邮政编码区的人口
- area - 以 km2 为单位的邮政编码扇区的表面积
- pop.dens - 是邮政编码区的人口密度,以每平方公里的人为单位
- rank - 根据每个地方当局的人口密度对邮政编码区段的排名
- LA.4G - 地方当局 4G 覆盖率
- LA.area - 每个地方当局的区域列的总和
- LA.4G(km2) - 每个地方当局内具有 4G 覆盖的 km2 的数量
以剑桥为例,整个地方政府的4G覆盖率为58%。然后我想分解这个数字以实现各个邮政编码区域的 4G 覆盖。
理想情况下,数据最终看起来像这样,并为邮政编码扇区覆盖范围增加一列:
Name pcd.sect ... pcd.sector.coverage (%)
Cambridge 1 ... 100
Cambridge 2 ... 100
Cambridge 3 ... 100
Cambridge 4 ... 34
Cambridge 5 ... 0
... ... ... ...
如何让 R 根据区域列将这 82 平方公里(58% 的地理覆盖范围)分配给新列中的邮政编码扇区,然后在达到 82 平方公里(58%)的最大覆盖水平后停止地理覆盖率百分比)?
这就是我对这个问题的解释。如果这不是你的意思,请纠正我。 假设你有以下数据。
dat <- data.frame(
Name = "A", pcd.sector = 1:5,
area = c(2, 3, 1, 5, 3),
areaSum = 14, LA.4G = 8
)
dat
# Name pcd.sector area areaSum LA.4G
#1 A 1 2 14 8
#2 A 2 3 14 8
#3 A 3 1 14 8
#4 A 4 5 14 8
#5 A 5 3 14 8
你有五个扇区,有不同的区域。虽然加起来有14个,但4G覆盖的只有8个。您想分配扇区 1 到 5 的区域。
以下代码完成这项工作。我使用 cumsum
函数计算顶部扇区的面积累计和,该扇区受 4G 覆盖限制的限制。分配的区域可以通过 diff
函数计算,该函数采用向量的一步差。扇区 1 到 3 获得 100% 的覆盖率,总共有 6 个区域,因此只剩下 2 个。 4区虽然有5区,但只能享受2区,也就是40%。这用完了区域,扇区 5 没有留下任何东西。
dat$area_allocated <- diff(c(0, pmin(cumsum(dat$area), dat$LA.4G)))
dat$area_coverage <- dat$area_allocated / dat$area * 100
dat
# Name pcd.sector area areaSum LA.4G area_allocated area_coverage
# 1 A 1 2 14 8 2 100
# 2 A 2 3 14 8 3 100
# 3 A 3 1 14 8 1 100
# 4 A 4 5 14 8 2 40
# 5 A 5 3 14 8 0 0
如果您有很多区域,那么您可能需要使用 dplyr::group_by
功能。
dat <- rbind(
data.frame(
Name = "A", pcd.sector = 1:5,
area = c(2, 3, 1, 5, 3),
areaSum = 14, LA.4G = 8
),
data.frame(
Name = "B", pcd.sector = 1:3,
area = c(4, 3, 2),
areaSum = 9, LA.4G = 5
)
)
library(dplyr)
dat <- dat %>% group_by(Name) %>%
mutate(area_allocated = diff(c(0, pmin(cumsum(area), LA.4G)))) %>%
mutate(area_coverage = area_allocated / area * 100)
dat
# Name pcd.sector area areaSum LA.4G area_allocated area_coverage
# <fctr> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 A 1 2 14 8 2 100.00000
# 2 A 2 3 14 8 3 100.00000
# 3 A 3 1 14 8 1 100.00000
# 4 A 4 5 14 8 2 40.00000
# 5 A 5 3 14 8 0 0.00000
# 6 B 1 4 9 5 4 100.00000
# 7 B 2 3 9 5 1 33.33333
# 8 B 3 2 9 5 0 0.00000