我在英国的地方政府有4G移动覆盖,按地理覆盖面积的百分比计算(大约200个地区)。我想分解这些数据,这样我就可以处理大约9000个较低水平的邮政编码扇区。
对我来说,最合适的方法是首先将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 -基于每个地方当局的人口密度的邮政编码部门排名
- 。4G -使用4G 的地方政府覆盖率%
- 。area—每个地方当局的area列之和
- LA.4G(km2) -在每个地方当局内4G覆盖的平方公里数
以剑桥为例,整个地方政府的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个,但只有8个覆盖了4G。您想要从扇区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