Here is a solution based on tidyverse.
Create df target
Because Area C doesn't have a Stop Area clearly indicated between Area2-3-4, we need to replace the missing value in Area2 with Area1 when Area2-3-4 are missing. Note we use rowwise and c_across to instruct our code to check row by row.
At that point you just reshape your data with pivot_longer and you remove all NAs by specifying values_drop_na = TRUE.
Last touch: you can define StartArea and StopArea for each ID and Veh.
library(tidyr)
library(dplyr)
df1 <- df1 %>%
rowwise() %>%
mutate(Area2 = if_else(all(is.na(c_across(c(Area2, Area3, Area4)))), Area1, Area2)) %>%
pivot_longer(starts_with("Area"), values_drop_na = TRUE) %>%
group_by(ID, Veh) %>%
summarise(StartArea = value[-length(value)],
StopArea = value[-1],
.groups = "drop")
df1
#> # A tibble: 11 x 4
#> ID Veh StartArea StopArea
#> <int> <chr> <chr> <chr>
#> 1 1 Veh 1 Area A Area B
#> 2 2 Veh 2 Area C Area C
#> 3 3 Veh 3 Area D Area A
#> 4 4 Veh 4 Area E Area F
#> 5 4 Veh 4 Area F Area D
#> 6 4 Veh 4 Area D Area A
#> 7 5 Veh 5 Area H Area B
#> 8 5 Veh 5 Area B Area C
#> 9 6 Veh 6 Area J Area K
#> 10 6 Veh 6 Area K Area A
#> 11 6 Veh 6 Area A Area B
Count
To count the frequency you can use count:
df1 %>% count(StartArea, StopArea)
#> # A tibble: 9 x 3
#> StartArea StopArea n
#> <chr> <chr> <int>
#> 1 Area A Area B 2
#> 2 Area B Area C 1
#> 3 Area C Area C 1
#> 4 Area D Area A 2
#> 5 Area E Area F 1
#> 6 Area F Area D 1
#> 7 Area H Area B 1
#> 8 Area J Area K 1
#> 9 Area K Area A 1
If you want to count the couples of Areas that are connected and you do not care about the direction, then you need to sort each row first.
df2 <- df1 %>% select(StartArea,StopArea)
df2[] <- asplit(apply(df2, 1, sort), 1) # sort by row
df2 %>% count(StartArea, StopArea)
#> # A tibble: 9 x 3
#> StartArea StopArea n
#> <chr> <chr> <int>
#> 1 Area A Area B 2
#> 2 Area A Area D 2
#> 3 Area A Area K 1
#> 4 Area B Area C 1
#> 5 Area B Area H 1
#> 6 Area C Area C 1
#> 7 Area D Area F 1
#> 8 Area E Area F 1
#> 9 Area J Area K 1
Data
df1 <- structure(list(ID = 1:6, Veh = c("Veh 1", "Veh 2", "Veh 3", "Veh 4",
"Veh 5", "Veh 6"), Area1 = c("Area A", "Area C", "Area D", "Area E",
"Area H", "Area J"), Area2 = c("Area B", NA, "Area A", "Area F",
"Area B", "Area K"), Area3 = c(NA, NA, NA, "Area D", "Area C",
"Area A"), Area4 = c(NA, NA, NA, "Area A", NA, "Area B")),
class = "data.frame", row.names = c(NA, -6L))