Позвольте мне оставить то, что я пробовал с подходом Tidyverse. Я разделил данные на ID
. (У вас есть только один идентификатор, но у вас может быть несколько идентификаторов. Поэтому я решил go таким образом.) Для каждого компонента списка я выбрал столбцы в диапазоне от Start
до Border_lat
, транспонировал, не включил их в список, затем создал матрица. Я заполнил эту матрицу тремя столбцами (city, lon и lat) и преобразовал матрицу во фрейм данных. Для каждой группы идентификаторов я добавил новый столбец с именем Type
. Я повторил Start
и Border
здесь. Наконец, я изменил имена столбцов и преобразовал lon
и lat
в цифру c. Я уверен, что есть краткие способы справиться с этим.
library(dplyr)
library(purrr)
map_dfr(.x = split(df, f = df$ID),
.f = function(x){dplyr::select(x, Start:Border_lat) %>%
t %>%
unlist %>%
matrix(ncol = 3, byrow = TRUE) %>%
as.data.frame(stringsAsFactors = FALSE)},
.id = "ID") %>%
group_by(ID) %>%
mutate(Type = rep(c("Start", "Border"), times = n()/2)) %>%
rename(stop = "V1", lon = "V2", lat = "V3") %>%
mutate_at(vars(lon:lat),
.funs = list(~as.numeric(.)))
# ID stop lon lat Type
# <chr> <chr> <dbl> <dbl> <chr>
# 1 1 Brussels 4.36 50.8 Start
# 2 1 Baisieux 3.08 50.6 Border
# 3 1 Lille 3.08 50.6 Start
# 4 1 Frethun 1.81 50.9 Border
# 5 1 Dover 1.30 51.1 Start
# 6 1 London -0.124 51.5 Border
# 7 2 Brussels 4.36 50.8 Start
# 8 2 Baisieux 3.08 50.6 Border
# 9 2 Lille 3.08 50.6 Start
#10 2 Frethun 1.81 50.9 Border
#11 2 Dover 1.30 51.1 Start
#12 2 London -0.124 51.5 Border
Другой вариант
Это идея с data.table. Исходя из того, что вы сказали, количество столбцов равно 8, а количество строк варьируется для каждого идентификатора. Учитывая это, я придумал следующий путь.
df[, .(Stop = c(Start, Border),
Type = c("Start", "Border"),
lon = c(Start_lon, Border_lon),
lat = c(Start_lat, Border_lat)),
by = .(ID, Sub_ID)]
# ID Sub_ID Stop Type lon lat
# 1: 1 1 Brussels Start 4.3570964 50.84550
# 2: 1 1 Baisieux Border 3.0756850 50.61848
# 3: 1 2 Lille Start 3.0756850 50.63909
# 4: 1 2 Frethun Border 1.8112210 50.90148
# 5: 1 3 Dover Start 1.3047866 51.12623
# 6: 1 3 London Border -0.1244124 51.53165
# 7: 2 1 Brussels Start 4.3570964 50.84550
# 8: 2 1 Baisieux Border 3.0756850 50.61848
# 9: 2 2 Lille Start 3.0756850 50.63909
#10: 2 2 Frethun Border 1.8112210 50.90148
#11: 2 3 Dover Start 1.3047866 51.12623
#12: 2 3 London Border -0.1244124 51.53165
ДАННЫЕ
df <- structure(list(ID = c(1, 1, 1, 2, 2, 2), Sub_ID = c(1L, 2L, 3L,
1L, 2L, 3L), Start = c("Brussels", "Lille", "Dover", "Brussels",
"Lille", "Dover"), Start_lon = c(4.3570964, 3.075685, 1.3047866,
4.3570964, 3.075685, 1.3047866), Start_lat = c(50.845504, 50.6390876,
51.12623, 50.845504, 50.6390876, 51.12623), Border = c("Baisieux",
"Frethun", "London", "Baisieux", "Frethun", "London"), Border_lon = c(3.075685,
1.811221, -0.1244124, 3.075685, 1.811221, -0.1244124), Border_lat = c(50.61848,
50.90148, 51.53165, 50.61848, 50.90148, 51.53165)), row.names = c(NA,
-6L), class = c("data.table", "data.frame"))