我有一个包含大约 150 万个人的数据集,可以通过“家庭 ID”在他们的家庭中进行区分。该数据集有一列(关系),根据家庭成员与户主的关系指定家庭成员之间的关系。 “代码1”指的是户主; “代号2”是团长的妻子; “code 3”是head的孩子; “代码4”为低女儿、低儿子(如果性别代码为1,则为低儿子,2为儿媳妇); “代码5”指的是头的孙子。 “代码6”指的是根据性别而定的头部的母亲或父亲; “Code 7”是头的兄弟或姐妹,这里同样是根据他们的性别; “代码8”指其他亲属,“代码9”指家庭中不被视为亲属(非亲属)的其他人。接下来我带来了我的数据集的一个小样本:
```library(tidyverse)
sample <- tibble(
household.ID = c(12850540085,12850540085,12850540085,12850540085,11854478630,11854478630,11854478630,11854478630,11854478630,243851633,243851633,243851633,243851633,243851633,243851633 ,243851633,243851633,243851633,243851633,16523634,16523634,16523634,16523634,16525912,16525912,16540127,16540127,16598050,16598050,16611764,16611764,16611764,16643309,16643309,16652356,16652356,16652356,16672105,16672105,16672105,16672105, 14347606936,14347606936,14513544764,14513544764,14513544764,14513544764,14513544764 ),
member.ID= c(12850560156, 12850560381, 12850560592,12850560795,23529759,23529760,23529761,23529762 ,23529763,243936326,243946420 ,243953196 ,243963749,243969681 ,243976774,243982427,243988959 ,243995522 ,244060815 ,16527193, 16529443, 16532250, 16534992,16527527, 16529230,16542499,16545263, 16616975, 16620223, 16633984,16642611,16650837,16646986,16650210, 16660335, 16665128,16668381,16676674, 16681528, 16685073,16687491, 14347619183,14347619282,14513560002,14513560086,14513560144,14513560214,14513560291),
relationship = c(1,2,3,5,1,9,3,6,9,1,2,3,3,3,6,9,7,8,8,1,2,3,3,1,2,1,2,1,3,1,2,3,1,2,1,2,3,1,2,3,3,1,7,1,2,4,5,5),
gender = c(1,2,2,1,1,2 ,2 ,2,1,1,2,2 ,2,2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,1,1,2,1,1,2,1,2,2,1,2,1,1,1,1,1,2,2,1,1),
age = c(64,58,38,6,42,42,1,76,19,61,59,35,33,29,96,28,45,43,15,49,47,19,18,38,28,78,75,66,21,56,52,28,51,58,74,68,27,56,43,23,13,45,42, 65 ,58 ,29,4 ,0),
marriage.status= c(1,1,1,4,1,1,4,2,1,1,1,4,1,1,2,4,1,1,4,1,1,4,4,1,1,1,1,2,4,1,1,1,1,1,1,1,4,1,1,4,4,4,4,1,1,2,4,4),
children.ever.born= c(NA,7,3,NA,NA,2,NA,9,NA,NA,3,NA,NA,NA,NA,NA,NA,1,NA ,NA,2,NA,NA,NA,NA,NA,6,NA,NA,NA,2,NA,NA,3,NA,3,NA,NA,2,NA,NA,NA,NA,NA,8,2,NA,NA),
living.children = c(NA,5,3,NA,NA,2,NA,6,NA,NA,3,NA,NA,NA,NA,NA,NA,1,NA,NA,2,NA,NA,NA,NA,NA,4,NA,NA,NA,2,NA,NA,3,NA,3,NA,NA,2,NA,NA,NA,NA,NA,4,2,NA,NA ))```
虽然看起来很残酷,但我想将上述代码链接起来,将孩子和他们的母亲联系起来。例如,“代码2”中的人是“代码3”中的母亲。或者,如果户主是女性(性别 2),那么“代码 3”就是他们的孩子,如果“代码 3”和性别(2)是“代码 4”的母亲,但这里有一个例外。如果你看一下数据,在一些家庭中我们可以看到,家里没有“代码4”,但我们家里有“代码5”。在这里,那些孙辈与“代码3”有关,他们有孩子并住在父母家里。 (见下表)
性别为(2)的“代码6”是“代码7”的母亲和户主。这里存在一个关于具有“代码 8”的其他亲属和具有“代码 9”的非亲属的挑战。母亲指定这些代码(8 和 9),没有代码来指代她们的孩子,但是当家庭中有一个人具有“代码 8 和 9”并且她已婚并且根据“居住”栏有一个孩子时。孩子”,即家庭中具有类似代码的任何其他孩子,根据家庭的接近程度,是妇女的孩子。为了说明这一点,请考虑下表,它是数据集中具有类似家庭的家庭之一。身份证。
我们的程序是不断循环遍历每个家庭,寻找我所描述的关系/性别配对,从明确的配对(例如孩子-母亲)开始,到可能有多个潜在母亲的配对(例如,母亲)结束。 ,孙子)。例如,根据关系列,第 1 行是“代码 1:户主,男性。 “代码2”是一名女性,是户主的配偶,根据“曾经出生的孩子”一栏,她到目前为止已经有3个孩子,并且所有孩子都在家里,但情况并非总是如此。代码 3 是代码 2 的子代。代码 6 是基于性别 (1) 的头部的父亲。代码 9 是非亲属,家里只有一人。根据性别,代码 7 是头部的兄弟。这里的代码8需要更多解释。我们家中有两个代码为8的人,都是女性,根据“在世子女”一栏,第一个有一个孩子;因此,我们可以得出结论,第二个代码为 8 的个体是第一个个体的女儿。根据母亲的年龄,这种联系是合乎逻辑的。最后,我想要一个如下表所示的输出,其中有一个新列,其中填充了个人母亲的 member.ID(如果存在)。
这里有一个通用方法的建议。定义要检测的链接,将其放入表中,然后将数据连接到这些表中。例如,我们可以制作一个表格,其中 8 与每个家庭中的 2 相匹配:
sample2 <- select(sample, 1:3) # we only need the first 3 columns
mother_links <- left_join(
sample2 %>% filter(relationship == 2),
sample2 %>% filter(relationship == 8) %>%
rename(member.ID.mother = member.ID), join_by(household.ID)) %>%
filter(!is.na(relationship.y)) %>%
select(1:2, member.ID.mother)
所以我们这里有这些人的链接:
> mother_links
# A tibble: 2 × 3
household.ID member.ID member.ID.mother
<dbl> <dbl> <dbl>
1 243851633 243946420 243995522
2 243851633 243946420 244060815
至于描述的第二个链接:
sample3 <- select(sample, 1:3, gender, age, living.children)
other_links <- left_join(
sample3%>% filter(relationship == 8, is.na(living.children)),
sample3 %>%
filter(relationship == 8, gender == 2, living.children > 0) %>%
rename(member.ID.mother = member.ID),
join_by(household.ID)
) %>%
select(1:2, member.ID.mother)
> other_links
# A tibble: 1 × 3
household.ID member.ID member.ID.mother
<dbl> <dbl> <dbl>
1 243851633 244060815 243995522
然后我们可以将它们与原始数据连接起来以查看如您的示例所示的结果:
sample %>%
left_join(bind_rows(mother_links, other_links)) %>%
filter(household.ID == 243851633)
Joining with `by = join_by(household.ID, member.ID)`
# A tibble: 10 × 9
household.ID member.ID relationship gender age marriage.status children.ever.born living.children member.ID.mother
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 243851633 243936326 1 1 61 1 NA NA NA
2 243851633 243946420 2 2 59 1 3 3 NA
3 243851633 243953196 3 2 35 4 NA NA 243946420
4 243851633 243963749 3 2 33 1 NA NA 243946420
5 243851633 243969681 3 2 29 1 NA NA 243946420
6 243851633 243976774 6 1 96 2 NA NA NA
7 243851633 243982427 9 2 28 4 NA NA NA
8 243851633 243988959 7 1 45 1 NA NA NA
9 243851633 243995522 8 2 43 1 1 1 NA
10 243851633 244060815 8 2 15 4 NA NA 243995522