【问题标题】:How to add family number to parents-childrens table如何将家庭号码添加到亲子表
【发布时间】:2018-04-05 10:54:09
【问题描述】:

我的数据: 关于 2 个家庭的信息:“Guillou”和“Cleach”。 人名 (person)、父亲姓名 (father) 和家庭排名 (level)。我现实中的名字很重要。我使用数字 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_Mudskipper 的回答(关于家谱中级别的上一个问题this post

这里是返回表格的说明:

数据:

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)

递归函数:

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

函数输出示例:

  father_line ("Guillou Alan")
 "Guillou Alan"   "Guillou Eric"   "Guillou Arthur"

表:

 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)

【问题讨论】:

  • 你是说有可能有两个Guillou Arthur,他们的父亲是NA,意思是两个同名的族长?
  • 是的:我可以找到很多同音词。实际上,我使用的是个人唯一 ID。
  • 我在问题中使用 id 添加了数据
  • 所以如果你有一个唯一的个人ID,你可以为每个父亲是NA的人设置一个唯一的家庭ID,你不能吗?
  • 我不太明白你的提议

标签: r recursion tree dplyr tidyverse


【解决方案1】:

你可能想看看包igraph

在使用它之前,您需要更改NAs,我假设您不能有 2 个来自同一家庭的 NA。
所以:

roots <- family[is.na(family)] <- seq(sum(is.na(family)))

然后您创建一个图(具有不同的连接),第一列需要是父亲:

library(igraph)
family_tree <- graph_from_data_frame(family[, 2:1])

您可以对其进行可视化:

plot(family_tree)

然后您可以使用distances 计算级别和家庭:

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

你必须要家庭 data.frame:

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

【讨论】:

  • 这是一个基于igraphpackage 的绝佳解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-10
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-28
  • 1970-01-01
相关资源
最近更新 更多