计算样带内线段的长度
Calculate the length of segments within a transect
我有一个包含纬度、经度和基质类型的样带数据。下面我提供了一个脚本,该脚本沿着从经度 -24.5 开始到 -23.2 结束的直线样带创建具有 3 种基质类型的假设数据。在此样带中,有 3 种基质类型(a、b 和 c),但基质类型 "a" 出现了 4 次,基质类型 "b" 出现了两次。我想计算样带中每个 "a"、"b" 和 "c" 基底类型段的总长度(米)。作为示例,基板段"a"在第一个观察到的"b"基板类型的位置结束并且基板段c在第四"a"基板类型段开始的位置结束。我想要的长度。我查看了 sp 和 Rdistance 包,但我真的卡住了。提前致谢。
假设示例:每个框表示我要计算其长度的每个段
Alon<-c(-23.20, -23.30,-23.40,-24.10,-24.15, -23.95, -23.70, -23.60,- 24.20, -24.25)
Blon<-c(-23.80, -23.85, -24.00, -24.03, -24.06)
Clon<-c(-23.47, -23.50,-23.55)
Alat<-c(64,64,64,64,64, 64, 64, 64,64, 64)
Blat<-c(64,64, 64, 64,64)
Clat<-c(64,64, 64)
A<-as.data.frame(cbind(Alon, Alat))
B<-as.data.frame(cbind(Blon, Blat))
C<-as.data.frame(cbind(Clon, Clat))
plot(A$Alon, A$Alat, pch=97)
points(B$Blon, B$Blat, col="red", pch=98)
points(C$Clon, C$Clat, col="blue", pch=99)
A$ID<-seq.int(nrow(A))
A[,3]<-"A"
B$ID<-seq.int(nrow(B))
B[,3]<-"B"
C$ID<-seq.int(nrow(C))
C[,3]<-"C"
colnames(A)<-c("lon", "lat", "ID")
colnames(B)<-c("lon", "lat", "ID")
colnames(C)<-c("lon", "lat", "ID")
A<-as.data.frame(A)
B<-as.data.frame(B)
C<-as.data.frame(C)
pos<- rbind(A,B,C)
pos<-pos[,c("ID","lon","lat")]
我怀疑以米为单位的长度取决于你的投影,所以在这里我计算以度为单位的长度,并将转换留给你。首先,我按经度排序(因为你们的纬度都一样)。
# Order data frame
pos <- pos[order(pos$lon),]
接下来,我使用 rle
提取每个 ID
的 运行。我添加 1 以在第一个元素上开始第一个 运行,并使用 pmin
确保最终索引不大于数据框中的行数。
# Pull out start and end points of segments
df_seg <- pos[pmin(nrow(pos), c(1, cumsum(rle(pos$ID)$lengths) + 1)),]
最后,我用diff
计算每个运行的起点和终点经度的差值。
# Calculate difference in longitude
data.frame(ID = df_seg$ID[1:(nrow(df_seg)-1)], diff_lon = abs(diff(df_seg$lon)))
# Check data frame
# ID diff_lon
# 1 A 0.19
# 2 B 0.11
# 3 A 0.10
# 4 B 0.15
# 5 A 0.15
# 6 C 0.15
# 7 A 0.20
关于订购站
我希望我有一个好的解决方案,但我没有。所以,我会在做一些糟糕的事情之前道歉...
library(dplyr)
library(RANN)
# Temporary data frame
df_stations <- pos
# Function for finding order of stations
station_order <- function(){
# If only one row, return it (i.e., it's the final station)
if(nrow(df_stations) == 1)return(df_station)
# Find the nearest neighbour for the first station
r <- nn2(data = df_stations %>% select(lon, lat), k = 2)$nn.idx[1,2]
# Bump the nearest neighbour to first in the data frame
# This also deletes the first entry
df_stations[1, ] <<- df_stations[r, ]
# Drop the nearest neighbour elsewhere in the data frame
df_stations <<- df_stations %>% distinct
# Return the nearest neighbour
return(df_stations[1, ])
}
# Initialise data frame
res <- df_stations[1,]
# Loop over data frame
for(i in 2:nrow(df_stations))res[i, ] <- station_order()
此代码使用最近邻(即 RANN
中的 nn2
)对您的电台进行排序。您会注意到横断面是倒置的,但您始终可以使用 res[nrow(res):1, ]
.
更改它
# ID lon lat
# 1 A -23.20 64
# 2 A -23.30 64
# 3 A -23.40 64
# 4 C -23.47 64
# 5 C -23.50 64
# 6 C -23.55 64
# 7 A -23.60 64
# 8 A -23.70 64
# 9 B -23.80 64
# 10 B -23.85 64
# 11 A -23.95 64
# 12 B -24.00 64
# 13 B -24.03 64
# 14 B -24.06 64
# 15 A -24.10 64
# 16 A -24.15 64
# 17 A -24.20 64
# 18 A -24.25 64
我有一个包含纬度、经度和基质类型的样带数据。下面我提供了一个脚本,该脚本沿着从经度 -24.5 开始到 -23.2 结束的直线样带创建具有 3 种基质类型的假设数据。在此样带中,有 3 种基质类型(a、b 和 c),但基质类型 "a" 出现了 4 次,基质类型 "b" 出现了两次。我想计算样带中每个 "a"、"b" 和 "c" 基底类型段的总长度(米)。作为示例,基板段"a"在第一个观察到的"b"基板类型的位置结束并且基板段c在第四"a"基板类型段开始的位置结束。我想要的长度。我查看了 sp 和 Rdistance 包,但我真的卡住了。提前致谢。
假设示例:每个框表示我要计算其长度的每个段
Alon<-c(-23.20, -23.30,-23.40,-24.10,-24.15, -23.95, -23.70, -23.60,- 24.20, -24.25)
Blon<-c(-23.80, -23.85, -24.00, -24.03, -24.06)
Clon<-c(-23.47, -23.50,-23.55)
Alat<-c(64,64,64,64,64, 64, 64, 64,64, 64)
Blat<-c(64,64, 64, 64,64)
Clat<-c(64,64, 64)
A<-as.data.frame(cbind(Alon, Alat))
B<-as.data.frame(cbind(Blon, Blat))
C<-as.data.frame(cbind(Clon, Clat))
plot(A$Alon, A$Alat, pch=97)
points(B$Blon, B$Blat, col="red", pch=98)
points(C$Clon, C$Clat, col="blue", pch=99)
A$ID<-seq.int(nrow(A))
A[,3]<-"A"
B$ID<-seq.int(nrow(B))
B[,3]<-"B"
C$ID<-seq.int(nrow(C))
C[,3]<-"C"
colnames(A)<-c("lon", "lat", "ID")
colnames(B)<-c("lon", "lat", "ID")
colnames(C)<-c("lon", "lat", "ID")
A<-as.data.frame(A)
B<-as.data.frame(B)
C<-as.data.frame(C)
pos<- rbind(A,B,C)
pos<-pos[,c("ID","lon","lat")]
我怀疑以米为单位的长度取决于你的投影,所以在这里我计算以度为单位的长度,并将转换留给你。首先,我按经度排序(因为你们的纬度都一样)。
# Order data frame
pos <- pos[order(pos$lon),]
接下来,我使用 rle
提取每个 ID
的 运行。我添加 1 以在第一个元素上开始第一个 运行,并使用 pmin
确保最终索引不大于数据框中的行数。
# Pull out start and end points of segments
df_seg <- pos[pmin(nrow(pos), c(1, cumsum(rle(pos$ID)$lengths) + 1)),]
最后,我用diff
计算每个运行的起点和终点经度的差值。
# Calculate difference in longitude
data.frame(ID = df_seg$ID[1:(nrow(df_seg)-1)], diff_lon = abs(diff(df_seg$lon)))
# Check data frame
# ID diff_lon
# 1 A 0.19
# 2 B 0.11
# 3 A 0.10
# 4 B 0.15
# 5 A 0.15
# 6 C 0.15
# 7 A 0.20
关于订购站
我希望我有一个好的解决方案,但我没有。所以,我会在做一些糟糕的事情之前道歉...
library(dplyr)
library(RANN)
# Temporary data frame
df_stations <- pos
# Function for finding order of stations
station_order <- function(){
# If only one row, return it (i.e., it's the final station)
if(nrow(df_stations) == 1)return(df_station)
# Find the nearest neighbour for the first station
r <- nn2(data = df_stations %>% select(lon, lat), k = 2)$nn.idx[1,2]
# Bump the nearest neighbour to first in the data frame
# This also deletes the first entry
df_stations[1, ] <<- df_stations[r, ]
# Drop the nearest neighbour elsewhere in the data frame
df_stations <<- df_stations %>% distinct
# Return the nearest neighbour
return(df_stations[1, ])
}
# Initialise data frame
res <- df_stations[1,]
# Loop over data frame
for(i in 2:nrow(df_stations))res[i, ] <- station_order()
此代码使用最近邻(即 RANN
中的 nn2
)对您的电台进行排序。您会注意到横断面是倒置的,但您始终可以使用 res[nrow(res):1, ]
.
# ID lon lat
# 1 A -23.20 64
# 2 A -23.30 64
# 3 A -23.40 64
# 4 C -23.47 64
# 5 C -23.50 64
# 6 C -23.55 64
# 7 A -23.60 64
# 8 A -23.70 64
# 9 B -23.80 64
# 10 B -23.85 64
# 11 A -23.95 64
# 12 B -24.00 64
# 13 B -24.03 64
# 14 B -24.06 64
# 15 A -24.10 64
# 16 A -24.15 64
# 17 A -24.20 64
# 18 A -24.25 64