我有一个类似下面的excel工作表设置,并已加载为df:
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米的假设距离。
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输出:
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和
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等),将其他列中的值相互绘制,并导出所有绘图。
发布于 2020-08-11 02:33:32
首先,如果您计划以类似的方式处理单个帧,我通常建议不要存储到单个帧中。(有关“框架列表”的讨论,请参阅https://stackoverflow.com/a/24376207/3358272。)
为了演示使用/丢弃了哪些行,我将在此处添加$row。我的任何代码都不需要(也不需要)使用它,只是为了演示。
此外,您还提到了与第一个"1“的距离,但前4行没有前面的"1”。由于处理的其余部分假设第一行是有意义的行,因此我将把第一个"1“(本例中第5行)复制为第一行,以便后续的分组距离测量按预期工作。
为了便于分组,这里我将使用dplyr。
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“。
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。
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行与这两个点进行比较。
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比较:
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发布于 2020-08-11 02:55:09
您可以使用base R's dist(...)获得所有点之间的距离函数。以分钟纬度表示的100m大约是0.009,因此您可以查看distance_matrix对象以确定哪些点之间的距离小于100m。
请注意,这使用欧几里德距离,这对于lat/long中的短距离是可以的,但如果您将其用于超过几英里的长距离,则会遇到问题。
我已经为任何想要尝试解决方案的人提供了reprex -请随时将其添加到您的问题中。
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"))https://stackoverflow.com/questions/63344746
复制相似问题