R 如何将族号添加到父/子表中
我的数据: 关于两个家族的信息:“Guillou”和“Cleach”。 人名(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
人名
)、父亲姓名(父亲
)和家庭等级(级别
)。我知道名字很重要。我使用数字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您可能想看看packageigraph
在使用它之前,您需要更改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