У меня есть df, перечисляющий количество областей (df$area
) и областей, с которыми они граничат (df$next_area
). Исходя из этого я хочу получить аналогичный df, но с соседом его соседа. Я написал следующее, которое работает, но кажется чрезвычайно запутанным. Было ли лучшее решение?
library(dplyr)
library(tidyr)
df <- data.frame(area=c("A","A","B","B","C","C","C","D"),next_area=c("B","C","A" ,"C","A","B","D","C") )
df <- df %>% group_by(area) %>%
summarize(next_area = list(sort(unique(as.character(next_area)))))
df$next_area_exploded <- df$next_area
for(i in 1:nrow(df)){
for(j in 1:length(df$next_area[[i]])){
df$next_area_exploded[[i]][j] <- list(df$next_area_exploded[[which(df$area==df$next_area[[i]][j])]])
}
}
df$next_area_exploded <- lapply(df$next_area_exploded, function(x) unique(unlist(x)))
for(i in 1:nrow(df)){
df$next_next_area[[i]] <- df$next_area_exploded[[i]] [!df$next_area_exploded[[i]] %in% df$next_area[[i]]]
df$next_next_area[[i]] <- df$next_next_area[[i]][!df$next_next_area[[i]] %in% df$area[[i]]]
}
df <- df %>% unnest(next_next_area) %>%
group_by(area) %>%
mutate(col=paste0(seq_along(area),".add")) %>%
spread(key=col, value=next_next_area)
df$next_area<-NULL; df$next_area_exploded<-NULL
df_final <- df %>% gather(a,next_next,c(names(df) [grepl(".add",names(df))])) %>% select(-a) %>% filter(!is.na(next_next))