簡體   English   中英

獲取連接到R中的主要父節點的節點集

[英]Getting the set of nodes connected till the main parent node in R

我有一個包含6行3列的數據集。 第一列代表孩子,而第二列向前分配相應孩子的直系父母。 在此處輸入圖片說明

在上面,可以看到“ a”和“ b”沒有任何父母。 而“ c”只有一個父對象,即“ a”。 “ d”具有父母“ b”和“ c”,依此類推。

我需要的是:如果以孩子的身份輸入,則應該給我該孩子的所有祖先,包括孩子。

例如,“ f”是我選擇的孩子,則期望的輸出應為:{“ f”,“ d”,“ b”},{“ f”,“ d”,“ c”,“ a”},{“ f “,” e“,” b“},{” f“,” e“,” c“,” a“}。

注意:節點的順序無關緊要。

提前非常感謝您。

創建樣本數據。 注意這里使用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

我們看到ef是不可訪問的,因此不是d祖先。 cb是直接父母, 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM