R 如何将族号添加到父/子表中

R 如何将族号添加到父/子表中,r,recursion,tree,dplyr,tidyverse,R,Recursion,Tree,Dplyr,Tidyverse,我的数据: 关于两个家族的信息:“Guillou”和“Cleach”。 人名(人名)、父亲姓名(父亲)和家庭等级(级别)。我知道名字很重要。我使用数字id来避免同音异义词的问题 person father level Guillou Arthur NA 1 Cleach Marc NA 1

我的数据: 关于两个家族的信息:“Guillou”和“Cleach”。 人名(
人名
)、父亲姓名(
父亲
)和家庭等级(
级别
)。我知道名字很重要。我使用数字id来避免同音异义词的问题

            person           father         level
            Guillou Arthur     NA           1       
            Cleach  Marc       NA           1       
            Guillou Eric    Guillou Arthur  2       
            Guillou Jacques Guillou Arthur  2       
            Cleach Franck   Cleach Marc     2       
            Cleach Leo      Cleach Marc     2       
            Cleach Herbet   Cleach Leo      3       
            Cleach Adele    Cleach Herbet   4       
            Guillou Jean    Guillou Eric    3       
            Guillou Alan    Guillou Eric    3
此数据框基于@Moody_Mudscapper答案(上一个关于家谱中级别的问题)

以下是返回表格的说明:

数据:

person <- c("Guillou Arthur",
          "Cleach Marc",
          "Guillou Eric",
          "Guillou Jacques", 
          "Cleach Franck",
          "Cleach Leo",
          "Cleach Herbet",
          "Cleach Adele",
          "Guillou Jean",
          "Guillou Alan" )
father <- c(NA, NA, "Guillou Arthur" , "Guillou Arthur", "Cleach Marc", "Cleach Marc", "Cleach Leo", "Cleach Herbet", "Guillou Eric", "Guillou Eric")


 family <- data.frame(person, father, stringsAsFactors = FALSE)
表:

 library(tidyverse)
 family %>%
 mutate(family_line = map(person,father_line),
     level = lengths(family_line),
     patriarch = map(family_line,last)) %>%
  select(person,father,level)
我的问题: 我如何根据个人/父亲关系区分这两个家庭?考虑到我不能使用家庭的名字:在我的可复制示例中,家庭有不同的名字,但在现实中没有

预期产出:

            person           father         level   family
            Guillou Arthur     NA           1       1
            Cleach  Marc       NA           1       2
            Guillou Eric    Guillou Arthur  2       1
            Guillou Jacques Guillou Arthur  2       1
            Cleach Franck   Cleach Marc     2       2
            Cleach Leo      Cleach Marc     2       2
            Cleach Herbet   Cleach Leo      3       2
            Cleach Adele    Cleach Herbet   4       2
            Guillou Jean    Guillou Eric    3       1
            Guillou Alan    Guillou Eric    3       1
有身份证

    # data
    person <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    father <- c(NA, NA, 1 , 1, 2, 2, 6, 7, 3, 3)


     family <- data.frame(person, father)



     # function
     father_line <- function(x){
     dad <- subset(family,person==x)$father
     if(is.na(dad)) return(x)
     c(x,father_line(dad))
     }




     library(tidyverse)
     family %>%
     mutate(family_line = map(person,father_line),
         level = lengths(family_line),
         patriarch = map(family_line,last)) %>%
      select(person,father,level)
#数据

person您可能想看看package
igraph

在使用它之前,您需要更改
NA
s,我假设您不能有两个人来自与NA相同的家庭。
因此:

然后,您可以使用到根的距离计算标高和族:

tab_roots <- sapply(roots, function(root) distances(family_tree, family$person, root))

您可能想看看包
igraph

在使用它之前,您需要更改
NA
s,我假设您不能有两个人来自与NA相同的家庭。
因此:

然后,您可以使用到根的距离计算标高和族:

tab_roots <- sapply(roots, function(root) distances(family_tree, family$person, root))

你是说可能有两个
Guillou Arthur
谁的父亲是
NA
,意思是两个同名的族长?是的:我可以找到许多同名词。实际上我使用个人唯一id。我在问题中使用id添加数据,所以如果你有唯一的个人id,你可以为每个人设置唯一的家庭id父亲是
NA
的人,不是吗?我真的不明白你的提议你是说可能有两个
Guillou Arthur
父亲是
NA
的人,意思是两个名字相同的族长?是的:我可以找到许多同名词。实际上我使用的是个人唯一id。我使用id添加数据在我的问题中,如果你有一个唯一的个人ID,你可以为每个父亲是
NA
的人设置一个唯一的家庭ID,不是吗?我真的不明白你的建议这是一个基于
igraph
package的伟大解决方案这是一个基于
igraph
package的伟大解决方案
roots <- family[is.na(family)] <- seq(sum(is.na(family)))
library(igraph)
family_tree <- graph_from_data_frame(family[, 2:1])
plot(family_tree)
tab_roots <- sapply(roots, function(root) distances(family_tree, family$person, root))
family$level <- apply(tab_roots, 1, min)
family$family <- apply(tab_roots, 1, function(d) which(d!=Inf))
family
#            person         father level family
#1   Guillou Arthur              1     1      1
#2      Cleach Marc              2     1      2
#3     Guillou Eric Guillou Arthur     2      1
#4  Guillou Jacques Guillou Arthur     2      1
#5    Cleach Franck    Cleach Marc     2      2
#6       Cleach Leo    Cleach Marc     2      2
#7    Cleach Herbet     Cleach Leo     3      2
#8     Cleach Adele  Cleach Herbet     4      2
#9     Guillou Jean   Guillou Eric     3      1
#10    Guillou Alan   Guillou Eric     3      1