我有城镇(从A到D),它们有不同的人口,并且距离不同。目标是将居住在半径圆(XY距离)内的总人口加起来,其中X是圆圈中心的城镇,Y是任何其他城镇。
在此代码中:
Df <- structure(list(Town_From = c("A", "A", "A", "B", "B", "C"), Town_To = c("B",
"C", "D", "C", "D", "D"), Distance = c(10, 5, 18, 17, 20, 21)), .Names = c("Town_From",
"Town_To", "Distance"), row.names = c(NA, -6L), class = "data.frame")
Df2 <- structure(list(Town = c("A", "B", "C", "D"), Population = c(1000,
800, 500, 200)), .Names = c("Town", "Population"), row.names = c(NA,
-4L), class = "data.frame")
Df <- Df %>% left_join(Df2,by=c("Town_From"="Town")) %>%
left_join(Df2,by=c("Town_To"="Town"))%>%
group_by(Town_From) %>%
arrange(Distance)
colnames(Df)[4]<-c("pop_TF")
colnames(Df)[5]<-c("pop_TT")
Source: local data frame [6 x 5]
Groups: Town_From [3]
Town_From Town_To Distance pop_TF pop_TT
<chr> <chr> <dbl> <dbl> <dbl>
1 A C 5 1000 500
2 A B 10 1000 800
3 B C 17 800 500
4 A D 18 1000 200
5 B D 20 800 200
6 C D 21 500 200
在5公里半径范围内(从A到C),活1000(A)+ 500(C)= 1500人;在下一个圈内活1500 + 800(在B中)= 2300。在第三圈内仍有2300人,因为城镇A,B,C在圆半径B到C = 17公里内。在圆半径A到D = 18km内,直播2300 + 200(在D中)= 2500人。
以下是相关圈子的可视化。从理论上讲,圆圈可以扩展到任意半径。在实践中,我只需要在城镇对之间的距离(计数变化的地方)检查它们。
答案 0 :(得分:4)
为此,如果您可以将数据放入每个城镇的每个城镇都有代表的格式,那就更容易了。&#34;结束&#34;距离(从和到)。因此,我将最后所做的更改更改为Df
。请注意,它使用complete
中的tidyr
。
Df_full <-
Df %>%
bind_rows(
select(Df, Town_From = Town_To, Town_To = Town_From, Distance)
) %>%
complete(Town_From, Town_To, fill = list(Distance = 0)) %>%
left_join(Df2, c("Town_To" = "Town"))
这会转换to-from关系并将其附加到列表的底部。然后,它使用complete
将城镇添加为自己的城镇&#34; To&#34; (例如,从A到A)。最后,它加入了人群,但现在只需要添加一次。这是新数据:
# A tibble: 16 × 4
Town_From Town_To Distance Population
<chr> <chr> <dbl> <dbl>
1 A A 0 1000
2 A B 10 800
3 A C 5 500
4 A D 18 200
5 B A 10 1000
6 B B 0 800
7 B C 17 500
8 B D 20 200
9 C A 5 1000
10 C B 17 800
11 C C 0 500
12 C D 21 200
13 D A 18 1000
14 D B 20 800
15 D C 21 500
16 D D 0 200
接下来,我们设置我们想要探索的阈值。在您的问题中,您暗示您想要使用每个独特的成对距离。如果您更喜欢其他一些产品用于生产,请在此处输入。
radiusCuts <-
Df_full$Distance %>%
unique %>%
sort
然后,我们构建一个sum
命令,该命令只对半径内的成对城市求和,在过程中设置名称,以便在一瞬间轻松使用summarise_
。
forPops <-
radiusCuts %>%
setNames(paste("Pop within", ., "km")) %>%
lapply(function(x){
paste("sum(Population[Distance <=", x,"])")
})
最后,我们group_by
Town_From
并将这些构建的参数传递给标准评估函数summarise_
,这将创建forPops
中的每一列:
Df_full %>%
group_by(Town_From) %>%
summarise_(.dots = forPops)
给出:
# A tibble: 4 × 8
Town_From `Pop within 0 km` `Pop within 5 km` `Pop within 10 km` `Pop within 17 km` `Pop within 18 km` `Pop within 20 km` `Pop within 21 km`
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 A 1000 1500 2300 2300 2500 2500 2500
2 B 800 800 1800 2300 2300 2500 2500
3 C 500 1500 1500 2300 2300 2300 2500
4 D 200 200 200 200 1200 2000 2500
哪个应该为您提供所需的所有阈值。
答案 1 :(得分:1)
如果您的目标是计算人口总和作为每个城镇(在圆心)增加距离的函数,那么我们可以(i)按Town_From
分组,(ii)排序每个组Distance
,然后(iii)计算cumsum
。使用dplyr
:
library(dplyr)
res <- Df %>% group_by(Town_From) %>%
arrange(Distance) %>%
mutate(sumPop=pop_TF+cumsum(pop_TT))
使用您的数据,结果是:
print(res)
##Source: local data frame [6 x 6]
##Groups: Town_From [3]
##
## Town_From Town_To Distance pop_TF pop_TT sumPop
## <chr> <chr> <dbl> <dbl> <dbl> <dbl>
##1 A C 5 1000 500 1500
##2 A B 10 1000 800 2300
##3 B C 17 800 500 1300
##4 A D 18 1000 200 2500
##5 B D 20 800 200 1500
##6 C D 21 500 200 700