【问题标题】:R:Identifying points inside a circle and calculating a new column based on two dataframesR:识别圆内的点并根据两个数据框计算新列
【发布时间】:2017-04-18 22:16:03
【问题描述】:

我有一个如下示例数据集

   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)
   Df<-data.frame(Town_From,Town_To,Distance)

 Town_From Town_To  Distance 
    A         B        10     
    A         C         5     
    A         D        18     
    B         C        17     
    B         D        20     
    C         D        21      

我有另一个数据框 (Df2),其中包含人口值

   Town<-c("A","B","C","D")
   Population<-c(1000,800,500,200)
   Df2<-data.frame(Town,Population)

  Town  Population
   A     1000
   B      800
   C      500
   D      200

我需要的是一个作为“Pop_within_Distance”的计算列

  Town_From Town_To  Distance  Pop_within_Distance
    A         B        10      2300
    A         C         5      1500
    A         D        18      2500
    B         C        17      1300
    B         D        20      1500
    C         D        21      700

Town_From 是我的 Origin,我需要将“Town_From”和“Town_To”半径内的城镇人口总和计算为“Pop_within_Distance”

例如,

在第一行,“Pop_within_Distance” = Pop_A + Pop_B + Pop_C =1000+800+500=2300(这是因为城镇 A、B 和 C 位于距离城镇 A 为 10 的圆内)

在第 4 行,“Pop_within_Distance” = Pop_B + Pop_C = 800+500=1300 (这是因为,只有 B 镇和 C 镇位于 B 镇半径为 17 的圆内)

如何在 R 中计算?

【问题讨论】:

  • 这不是真正的编码问题;这是一道数学题。
  • @ulfelder 这是正确的家庭作业。 OP:如果是这样(即使不是)你尝试过什么失败了?

标签: r dplyr


【解决方案1】:

您可以使用 dplyr 执行此操作,因为我们首先转换您的数据框,以便 Town_FromTown_ToTown 列是字符而不是因子(或者它们是具有相同级别的因子) :

library(dplyr)
Df <- Df %>% left_join(Df2,by=c("Town_To"="Town")) %>% 
             group_by(Town_From) %>% 
             arrange(Distance) %>% 
             mutate(Pop_within_Distance=cumsum(Population)+Df2$Population[Df2$Town %in% Town_From]) %>%
             select(-Population) %>% arrange(Town_From,Town_To)
##Source: local data frame [6 x 4]
##Groups: Town_From [3]
##
##  Town_From Town_To Distance Pop_within_Distance
##      <chr>   <chr>    <dbl>               <dbl>
##1         A       B       10                2300
##2         A       C        5                1500
##3         A       D       18                2500
##4         B       C       17                1300
##5         B       D       20                1500
##6         C       D       21                 700

注意事项:

  1. 首先left_join Df 中的Town_ToTown 中的Df2 两个数据帧,这样我们就得到了这个中间结果:

      Town_From Town_To Distance Population
    1         A       B       10        800
    2         A       C        5        500
    3         A       D       18        200
    4         B       C       17        500
    5         B       D       20        200
    6         C       D       21        200
    
  2. Town_From 分组并使用arrangeDistance 对表进行排序。这里的重点是,我们现在可以在Population 上使用cumsum 来计算距离小于或等于当前行的城镇的总人口。

  3. 然后使用mutate 创建Pop_within_Distance 列,该计算将来自Df2 的原始城镇(即Town_From)人口相加。
  4. 最后,删除Population 列,返回原来的行顺序。

数据:

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")
##  Town_From Town_To Distance
##1         A       B       10
##2         A       C        5
##3         A       D       18
##4         B       C       17
##5         B       D       20
##6         C       D       21

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")
##  Town Population
##1    A       1000
##2    B        800
##3    C        500
##4    D        200

【讨论】:

  • 非常感谢您的描述性回答。我没有考虑排序和获得累积总和。相反,我在考虑如何用距离来识别圆内的点。这是一个简单且非常有用的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-11
  • 1970-01-01
  • 2015-08-09
  • 2019-11-29
  • 2023-01-08
相关资源
最近更新 更多