Рассчитать длину сегментов внутри разреза - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть данные разреза с широтой, долготой и типами субстрата.Ниже я приведу сценарий, который создает гипотетические данные с 3 типами субстрата вдоль прямого разреза, начиная с долготы -24,5 и заканчивая -23,2.В пределах этого трансекта существует 3 типа субстрата (a, b и c), но тип субстрата "a" встречается 4 раза, а тип субстрата "b" - дважды.Я хотел бы рассчитать общую длину (в метрах) каждого сегмента субстрата типа "a", "b" и "c" в разрезе.В качестве примера, сегмент подложки «a» заканчивается в положении первого наблюдения типа подложки «b», а сегмент подложки c заканчивается там, где начинается четвертый сегмент «a» типа подложки.Я бы хотел, чтобы длина.Я изучил пакеты sp и Rdistance, но я действительно застрял.С благодарностью заранее.

гипотетический пример : каждое поле обозначает каждый сегмент, для которого я хотел бы рассчитать длину hypothetical example: each box denote each segment for which I would like to calculate the length of

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")]

1 Ответ

0 голосов
/ 18 февраля 2019

Я подозреваю, что длина в метрах зависит от вашей проекции, поэтому здесь я рассчитываю длину в градусах и оставлю преобразование на ваше усмотрение.Во-первых, я заказываю по долготе (поскольку ваши широты все одинаковы).

# 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()

Этот код приказывает вашим станциям использовать ближайшего соседа (то есть nn2 из RANN).Вы заметите, что трансект перевернут, но вы всегда можете изменить его с помощью 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
...