r - 查找邻居的邻居
问题描述
我有一个 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))
解决方案
您可以将其视为一个图形,并为每个节点找到距离为 2 的所有其他节点:
library(igraph)
df <- data.frame(area=c("A","A","B","B","C","C","C","D"),
next_area=c("B","C","A","C","A","B","D","C") )
g = graph_from_data_frame(df)
distances(g) %>%
as_tibble(rownames = 'area') %>%
gather(-area, key = 'next_next_area', value = 'distance') %>%
filter(distance == 2)
输出:
# A tibble: 4 x 3
area next_next_area distance
<chr> <chr> <dbl>
1 D A 2
2 D B 2
3 A D 2
4 B D 2
推荐阅读
- c++ - 以 Visual Studio 为目标的 Windows XP 的最新 C++ 标准是什么?
- python - python中的多行int输出?
- flutter - 动态修改图像不会更新屏幕上的图像
- java - 如何在 Swagger 代码生成中获取 ENUM 字段值?
- javascript - 如何在 ReactJS 中更新对象的 setstate
- javascript - d3 在 Firefox 中缩放 NaN
- swift - 显示没有 UIImage 的 base64 编码图像
- matlab - 如何在 plot3 中使用渐进式着色?
- entity-framework-core - 1 对多,以复合键为主键
- node.js - 如何确定与本地服务器日期和数据库日期的时区偏移