[英]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.