[英]Getting the set of nodes connected till the main parent node in R
創建樣本數據。 注意這里使用stringsAsFactors
,我假設您的數據是字符而不是因素:
> d <- data.frame(list("c" = c("a", "b", "c", "d", "e", "f"), "p1" = c(NA, NA, "a", "b", "b", "d"), "p2" = c(NA, NA, NA, "c", "c", "e")),stringsAsFactors=FALSE)
首先整理一下-使數據變長而不是變寬,每一行都是一對子對:
> pairs = subset(reshape2::melt(d,id.vars="c",value.name="parent"), !is.na(parent))[,c("c","parent")]
> pairs
c parent
3 c a
4 d b
5 e b
6 f d
10 d c
11 e c
12 f e
現在我們可以繪制父子關系圖。 這是一個有向圖,因此將父級繪制為箭頭:
> g = graph.data.frame(pairs)
> plot(g)
現在我不確定您到底想要什么,但是igraph
函數可以執行任何操作...因此,例如,從d
開始搜索圖,從中我們可以獲取各種信息:
> d_search = bfs(g,"d",neimode="out", unreachable=FALSE, order=TRUE, dist=TRUE)
首先, d
祖先是哪些節點? 可以通過詳盡的搜索(此處為廣度優先)從d
到達它:
> d_search$order
+ 6/6 vertices, named:
[1] d c b a <NA> <NA>
注意它也包括d
。 小到足以從該列表中刪除。 這樣就可以得到d
的祖先集。
這些節點與d
什么關系?
> d_search$dist
c d e f a b
1 0 NaN NaN 2 1
我們看到e
和f
是不可訪問的,因此不是d
祖先。 c
和b
是直接父母, a
是祖父母。 您可以從圖表中進行檢查。
您也可以從使用向上類似功能的任何孩子所有的路徑shortest_paths
等。
這是一個使所有可能的族系均行的遞歸函數:
d <- data.frame(list("c" = c("a", "b", "c", "d", "e", "f"),
"p1" = c(NA, NA, "a", "b", "b", "d"),
"p2" = c(NA, NA, NA, "c", "c", "e")), stringsAsFactors = F)
# Make data more convenient for the task.
library(reshape2)
dp <- melt(d, id = c("c"), value.name = "p")
# Recursive function builds ancestor vectors.
getAncestors <- function(data, x, ancestors = list(x)) {
parents <- subset(data, c %in% x & !is.na(p), select = c("c", "p"))
if(nrow(parents) == 0) {
return(ancestors)
}
x.c <- parents$c
p.c <- parents$p
ancestors <- lapply(ancestors, function(x) {
if (is.null(x)) return(NULL)
# Here we want to repeat ancestor chain for each new parent.
res <- list()
matches <- 0
for (i in 1:nrow(parents)) {
if (tail(x, 1) == parents[i, ]$c){
res[[i]] <- c(x, parents[i, ]$p)
matches <- matches + 1
}
}
if (matches == 0) { # There are no more parents.
res[[1]] <- x
}
return (res)
})
# remove one level of lists.
ancestors <- unlist(ancestors, recursive = F)
res <- getAncestors(data, p.c, ancestors)
return (res)
}
# Demo of results for the lowest level.
res <- getAncestors(dp, "f")
res
#[[1]]
#[1] "f" "d" "b"
#[[2]]
#[1] "f" "d" "c" "a"
#[[3]]
#[1] "f" "e" "b"
#[[4]]
#[1] "f" "e" "c" "a"
您將需要通過遞歸或while循環以類似的方式實現此目的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.