0

我有一个数据框,其中包含许多项目 + 他们的开始日期 + 他们的坐标(长/纬度),我有一个数据框,其中包含一些(虚构的)受访者 + 他们接受调查的日期 + 他们的坐标:

respond_id<- c(1:5)
survey_year<- c(2007, 2005, 2008, 2004, 2005)
lat_1<- c(53.780928, 54.025200, 53.931432, 53.881048, 54.083359)
long_1<- c(9.614991, 9.349862, 9.473498, 10.685581, 10.026894)

project_id<- c(1111:1114)
year_start<- c(2007, 2007, 2006, 2008)
lat_2<- c(54.022881, 54.022881, 53.931753, 53.750523)
long_2<- c(9.381104, 9.381104, 9.505700, 9.666336)

survey<- data.frame(respond_id, survey_year, lat_1, long_1)
projects<- data.frame(project_id, year_start, lat_2, long_2)

现在,我想创建一个新的变量survey$project_nearby来计算受访者附近(这里:5 公里)的项目数量。所以数据框survey应该看起来像这样(可能的其他结果):

> survey

  respond_id survey_year     lat_1    long_1 projects_nearby
1          1        2007 53.780928  9.614991               0
2          2        2005 54.025200  9.349862               0
3          3        2008 53.931432  9.473498               1
4          4        2004 53.881048 10.685581               0
5          5        2005 54.083359 10.026894               0

需要特别注意项目的开工年份和调查的年份:如果2007年被访者问到,但附近的项目是2008年完成的,这个项目自然不能算作附近的项目。

我想创建一个距离矩阵,然后只计算包含小于 5 公里距离的行数......但我不知道如何创建这个距离矩阵。也许 for 循环会更容易?谁能帮助我或给我一个提示,这样做的代码是什么?

编辑:我编辑了survey$projects_nearby 的预期值。现在,这些值应该与位于相应受访者附近的实际项目数量相匹配。

4

3 回答 3

1

我不认为正确的答案是显示?下面我left_join按年份,这样每一行survey都会为每个匹配复制projects。然后我过滤到纬度低于 5 公里的行。计算它们并重新加入原始调查。

由于同一年的项目 1 和 2 位于同一位置,因此结果也有点令人困惑。我用这段代码计算了两次。

>survey
  respond_id survey_year    lat_1    long_1
1          1        2007 53.78093  9.614991
2          2        2005 54.02520  9.349862
3          3        2008 53.93143  9.473498
4          4        2004 53.88105 10.685581
5          5        2005 54.08336 10.026894


>projects
> projects
  project_id year_start    lat_2   long_2
1       1111       2007 54.02288 9.381104
2       1112       2007 54.02288 9.381104
3       1113       2006 53.93175 9.505700
4       1114       2008 53.75052 9.666336

> left_join(survey, projects, by = c( "survey_year"="year_start")) %>%
+ dplyr::filter( sqrt((lat_1-lat_2)^2 + (long_1-long_2)^2 ) < 5) %>%
+   group_by(respond_id, survey_year, lat_1, long_1) %>%
+   summarise(projects_nearby = n()) %>%
+   right_join(survey)
Joining, by = c("respond_id", "survey_year", "lat_1", "long_1")
Source: local data frame [5 x 5]
Groups: respond_id, survey_year, lat_1 [?]

  respond_id survey_year    lat_1    long_1 projects_nearby
       <int>       <dbl>    <dbl>     <dbl>           <int>
1          1        2007 53.78093  9.614991               2
2          2        2005 54.02520  9.349862              NA
3          3        2008 53.93143  9.473498               1
4          4        2004 53.88105 10.685581              NA
5          5        2005 54.08336 10.026894              NA

..如果合适,您当然可以将 NA 更改为零...

于 2018-03-23T22:46:10.257 回答
0

我认为您必须将经纬度坐标转换为平面坐标,或使用上一篇文章中的以下链接:

收割距离

https://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula

一旦您有了到项目数据框中特定位置的距离,您可能需要使用或任何其他您喜欢的技术来查找similar点。knn

于 2018-03-23T22:28:36.013 回答
0

您可以使用sp包来查找距离,然后只计算附近的数字。那是,

library(sp)
survey.loc <- matrix(as.numeric(as.character(unlist(survey[, 3:4]))), ncol = 2)
project.loc <- matrix(as.numeric(as.character(unlist(projects[, 3:4]))), ncol = 2)
distances <- spDists(survey.loc, project.loc, longlat = TRUE)
survey$project_nearby <- apply(distances, 1, function(x) sum(x<5))

我希望这有帮助!

编辑:

我很抱歉没有考虑日期。

library(sp)
survey.loc <- matrix(as.numeric(as.character(unlist(survey[, 3:4]))), ncol = 2)
project.loc <- matrix(as.numeric(as.character(unlist(projects[, 3:4]))), ncol = 2)
distances <- spDists(survey.loc, project.loc, longlat = TRUE)
year.diff <- sapply(projects$year_start, function(x) survey$survey_year-x)
year.diff <- ifelse(year.diff < 0, Inf, 1)
survey$project_nearby <- apply(year.diff*distances, 1, function(x) sum(x<5))
于 2018-03-23T22:34:22.497 回答