首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据另一列中标记的特定半径内的经度和经度列中的值忽略行,然后创建新的数据框

根据另一列中标记的特定半径内的经度和经度列中的值忽略行,然后创建新的数据框
EN

Stack Overflow用户
提问于 2020-08-11 01:04:43
回答 2查看 68关注 0票数 0

我有一个类似下面的excel工作表设置,并已加载为df:

代码语言:javascript
复制
GPS_Lat     GPS_Lon     Location
50.70528    -120.44984  0
50.70528    -120.44984  0
50.70527    -120.44984  0
50.70527    -120.44984  0
50.70526    -120.44984  1
50.70526    -120.44984  1
50.70525    -120.44984  1
50.70525    -120.44984  0
50.70524    -120.44984  0
50.70524    -120.44984  0
50.70523    -120.44984  0
50.70523    -120.44984  0
50.70522    -120.44984  0
50.70522    -120.44984  0
50.70521    -120.44984  1
50.70521    -120.44984  1
50.7052     -120.44985  1
50.7052     -120.44985  1
50.70519    -120.44985  0
50.70519    -120.44986  0
50.70518    -120.44986  0
50.70518    -120.44986  0
50.70517    -120.44987  0
50.70517    -120.44987  0

我希望将值保持在位置列中遇到的第一个"1“的1m范围内,并将这些值放入一个新的数据框(名为: df-n)。如果还有其他部分的值为1,我想将它们分割成单独的数据帧(命名为: df-n+1),同时也只将点保持在第一个1的1m以内。我希望每个新数据帧都按顺序编号。在这一点上我完全被难住了。

自动识别下面的点,并使用原始数据框名称和顺序后缀为每个点创建行距在这些点1米内(或任何其他定义的距离)的新数据框。因此,原来的"df“第二个"df-1”和"df-2“

我最终将使用半径为10 km的数据集,我的数据集最多可以有20k行。

编辑:为输出提供清晰度。使用半径截断为2米的假设距离。

代码语言:javascript
复制
   Row  GPS_Lat    GPS_Lon     Location hypothetical_dist_1 hypothetical_dist_2 
    1   50.70528    -120.44984  0   4   14
    2   50.70528    -120.44984  0   3   13
    3   50.70527    -120.44984  0   2   12
    4   50.70527    -120.44984  0   1   11
    5   50.70526    -120.44984  1   0   10
    6   50.70526    -120.44984  1   1   9
    7   50.70525    -120.44984  1   2   8
    8   50.70525    -120.44984  0   3   7
    9   50.70524    -120.44984  0   4   6
    10  50.70524    -120.44984  0   5   5
    11  50.70523    -120.44984  0   6   4
    12  50.70523    -120.44984  0   7   3
    13  50.70522    -120.44984  0   8   2
    14  50.70522    -120.44984  0   9   1
    15  50.70521    -120.44984  1   10  0
    16  50.70521    -120.44984  1   11  1
    17  50.7052     -120.44985  1   12  2
    18  50.7052     -120.44985  1   13  3
    19  50.70519    -120.44985  0   14  4
    20  50.70519    -120.44986  0   15  5
    21  50.70518    -120.44986  0   16  6
    22  50.70518    -120.44986  0   17  7
    23  50.70517    -120.44987  0   18  8
    24  50.70517    -120.44987  0   19  9

输出:

代码语言:javascript
复制
df-1
Row GPS_Lat     GPS_Lon    Location hypothetical_dist_1 
3   50.70527    -120.44984  0       2
4   50.70527    -120.44984  0       1
5   50.70526    -120.44984  1       0
6   50.70526    -120.44984  1       1
7   50.70525    -120.44984  1       2

代码语言:javascript
复制
df-2
Row GPS_Lat     GPS_Lon    Location hypothetical_dist_2
13  50.70522    -120.44984  0       2
14  50.70522    -120.44984  0       1
15  50.70521    -120.44984  1       0
16  50.70521    -120.44984  1       1
17  50.7052     -120.44985  1       2

基本上,工作流程如下:将多个.csv文件批量加载到列表中,根据文件名命名列表项目,使用所选的半径分隔每个列表项目(文件名-1、文件名-2等),将其他列中的值相互绘制,并导出所有绘图。

EN

回答 2

Stack Overflow用户

发布于 2020-08-11 02:33:32

首先,如果您计划以类似的方式处理单个帧,我通常建议不要存储到单个帧中。(有关“框架列表”的讨论,请参阅https://stackoverflow.com/a/24376207/3358272。)

为了演示使用/丢弃了哪些行,我将在此处添加$row。我的任何代码都不需要(也不需要)使用它,只是为了演示。

此外,您还提到了与第一个"1“的距离,但前4行没有前面的"1”。由于处理的其余部分假设第一行是有意义的行,因此我将把第一个"1“(本例中第5行)复制为第一行,以便后续的分组距离测量按预期工作。

为了便于分组,这里我将使用dplyr

代码语言:javascript
复制
library(dplyr)
if (dat$Location[1] != 1) {
  prepended1 <- TRUE # in case we want to discard this copied row later
  # bring the first "1" to the top
  dat <- bind_rows(dat[which(dat$Location == 1)[1],,drop = FALSE], dat)
  dat$row[1] <- 0L
} else prepended1 <- FALSE

dat2 <- dat %>%
  mutate(grp = cumsum(c(TRUE, diff(Location) > 0))) %>%
  group_by(grp) %>%
  mutate(dist = geosphere::distVincentyEllipsoid(cbind(GPS_Lon, GPS_Lat), cbind(cbind(GPS_Lon[1], GPS_Lat[1])))) %>%
  ungroup()
dat2
# # A tibble: 25 x 6
#    GPS_Lat GPS_Lon Location   row   grp  dist
#      <dbl>   <dbl>    <int> <int> <int> <dbl>
#  1    50.7   -120.        1     0     1  0   
#  2    50.7   -120.        0     1     1  2.22
#  3    50.7   -120.        0     2     1  2.22
#  4    50.7   -120.        0     3     1  1.11
#  5    50.7   -120.        0     4     1  1.11
#  6    50.7   -120.        1     5     2  0   
#  7    50.7   -120.        1     6     2  0   
#  8    50.7   -120.        1     7     2  1.11
#  9    50.7   -120.        0     8     2  1.11
# 10    50.7   -120.        0     9     2  2.22
# # ... with 15 more rows

这提供了到“组中的第一个1”的距离(请注意grp变量)。在这里,可以很容易地按dist过滤并按grp拆分。

根据您的后续流程,使用dplyr::group_by保持这种单帧格式可能更好,尽管改编代码是一种不同的冒险。

您的所有数据(除了第一行本身)都不在1m以内,因此为了演示,我将使用"2m“。

代码语言:javascript
复制
dat2 %>%
  filter(dist <= 2)
# # A tibble: 11 x 6
#    GPS_Lat GPS_Lon Location   row   grp  dist
#      <dbl>   <dbl>    <int> <int> <int> <dbl>
#  1    50.7   -120.        1     0     1  0   
#  2    50.7   -120.        0     3     1  1.11
#  3    50.7   -120.        0     4     1  1.11
#  4    50.7   -120.        1     5     2  0   
#  5    50.7   -120.        1     6     2  0   
#  6    50.7   -120.        1     7     2  1.11
#  7    50.7   -120.        0     8     2  1.11
#  8    50.7   -120.        1    15     3  0   
#  9    50.7   -120.        1    16     3  0   
# 10    50.7   -120.        1    17     3  1.32
# 11    50.7   -120.        1    18     3  1.32

同样,我不会将其分解为单独的变量,而是将其保存为帧的list

代码语言:javascript
复制
lst_of_frames <- dat2 %>%
  filter(dist <= 2) %>%
  split(., .$grp)
lst_of_frames
# $`1`
# # A tibble: 3 x 6
#   GPS_Lat GPS_Lon Location   row   grp  dist
#     <dbl>   <dbl>    <int> <int> <int> <dbl>
# 1    50.7   -120.        1     0     1  0   
# 2    50.7   -120.        0     3     1  1.11
# 3    50.7   -120.        0     4     1  1.11
# $`2`
# # A tibble: 4 x 6
#   GPS_Lat GPS_Lon Location   row   grp  dist
#     <dbl>   <dbl>    <int> <int> <int> <dbl>
# 1    50.7   -120.        1     5     2  0   
# 2    50.7   -120.        1     6     2  0   
# 3    50.7   -120.        1     7     2  1.11
# 4    50.7   -120.        0     8     2  1.11
# $`3`
# # A tibble: 4 x 6
#   GPS_Lat GPS_Lon Location   row   grp  dist
#     <dbl>   <dbl>    <int> <int> <int> <dbl>
# 1    50.7   -120.        1    15     3  0   
# 2    50.7   -120.        1    16     3  0   
# 3    50.7   -120.        1    17     3  1.32
# 4    50.7   -120.        1    18     3  1.32

如果你需要突破它,可以很容易地手动分配它们(例如,lst_of_frames[[2]])。

让我们尝试一下这个不同的逻辑:

every point与every 进行比较。在这个数据中,有两个first-__1点(第5行和第15行),所以我们将把所有24行与这两个点进行比较。

代码语言:javascript
复制
compare_points <- filter(dat, Location == 1 & lag(Location) == 0)
compare_points
#    GPS_Lat   GPS_Lon Location row
# 1 50.70526 -120.4498        1   5
# 2 50.70521 -120.4498        1  15

比较:

代码语言:javascript
复制
lapply(seq_len(nrow(compare_points)), function(ind) {
  dat %>%
    mutate(dist = geosphere::distVincentyEllipsoid(compare_points[ind,2:1], cbind(GPS_Lon, GPS_Lat))) %>%
    filter(dist <= 2)
})
# [[1]]
#    GPS_Lat   GPS_Lon Location row     dist
# 1 50.70527 -120.4498        0   3 1.112426
# 2 50.70527 -120.4498        0   4 1.112426
# 3 50.70526 -120.4498        1   5 0.000000
# 4 50.70526 -120.4498        1   6 0.000000
# 5 50.70525 -120.4498        1   7 1.112426
# 6 50.70525 -120.4498        0   8 1.112426
# [[2]]
#    GPS_Lat   GPS_Lon Location row     dist
# 1 50.70522 -120.4498        0  13 1.112426
# 2 50.70522 -120.4498        0  14 1.112426
# 3 50.70521 -120.4498        1  15 0.000000
# 4 50.70521 -120.4498        1  16 0.000000
# 5 50.70520 -120.4498        1  17 1.317768
# 6 50.70520 -120.4498        1  18 1.317768
票数 1
EN

Stack Overflow用户

发布于 2020-08-11 02:55:09

您可以使用base R's dist(...)获得所有点之间的距离函数。以分钟纬度表示的100m大约是0.009,因此您可以查看distance_matrix对象以确定哪些点之间的距离小于100m。

请注意,这使用欧几里德距离,这对于lat/long中的短距离是可以的,但如果您将其用于超过几英里的长距离,则会遇到问题。

我已经为任何想要尝试解决方案的人提供了reprex -请随时将其添加到您的问题中。

代码语言:javascript
复制
latlong <- c(50.70528, 50.70528, 50.70527, 50.70527, 50.70526, 50.70526, 50.70525, 50.70525, 50.70524, 50.70524, 50.70523, 50.70523, 50.70522, 50.70522, 50.70521, 50.70521, 50.7052, 50.7052, 50.70519, 50.70519, 50.70518, 50.70518, 50.70517, 50.70517, -120.44984, -120.44984, -120.44984, -120.44984, -120.44984, -120.44984, -120.44984, -120.44984, -120.44984, -120.44984, -120.44984, -120.44984, -120.44984, -120.44984, -120.44984, -120.44984, -120.44985, -120.44985, -120.44985, -120.44986, -120.44986, -120.44986, -120.44987, -120.44987, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0)
latlong <- matrix(latlong, nrow = 24)
    
distance_matrix <- as.matrix(dist(latlong[,c(1,2)], method = "euclidean"))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63344746

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档