首页 > 解决方案 > 基于两个条件循环数据帧的子集

问题描述

我有以下问题:我需要运行数据帧的每个子集 - 基于变量的值 - 根据 2 个条件为另一个变量创建新条目。

数据框(dt3)如下:我有 4 个变量(birth_year、姓氏-Name-、家庭角色-role- 和家庭-hh-)。整个集合被 hh 变量划分或子集,该变量聚集了同一家庭下的所有个人。例如,在下面的示例中,前 4 行属于家庭“1”。此外,在可变角色下,仅提及户主。其余的角色都是空的,必须派生,这就是我想要做的。我的第一步是分配“孩子”的角色。我正在考虑通过在整个数据集和每个子集(每个 hh 值)上运行一个循环来做到这一点。如果每行有一个人与户主姓氏相同,并且出生年份比户主晚至少15年,则此人被推断为“孩子”。

原始数据框是:

birth_year       Name           role        hh

1877        Snijders    Head ofhousehold    1
1885        Marteen     NA                  1
1897        Snijders    NA                  1
1892        Zelstra     NA                  1
1878        Kuipers     Head of household   2
1870        Marteen     NA                  2
1897        Wals        NA                  2
1900        Venstra     NA                  2
1900        Lippe       Head of household   3
1905        Flachs      NA                  3
1920        Lippe       NA                  3
1922        Lippe       NA                  3

所以,我需要运行整个集合和每个 hh 子集并执行以下两个条件:如果这个人的名字==头的名字,并且b。如果人的出生年份与头部年龄相差 15 年或以上

那么这个人就是“孩子”。

到目前为止,我一直在尝试几件事。当我将头部角色放在每个家庭的第一行时,我正在这样做:

a)嵌套循环,我尝试运行数据集,然后每个 hh。对于每个 hh,我运行条件(通过将每一行的名称和出生年份与 hh 的第一行 - 头部 - 进行比较)

for (n in 1:unique(dt3$hh)){
  for (i in 1:length(which(dt3$hh==n)) ){ 
     mutate(dt3, role = ifelse( dt3$Name[[1,2]] == dt3$Name[[n,1]]    
     & dt3$birth_year[[n,i]] > dt3$birth_year[[n,1]], "children","NoA"))
      }
  }

还有b),我也尝试过这样做,但使用列表。我首先通过 hh 变量拆分 dt3

dt3 <- split(dt3, f = dt3$hh)

接着

for (n in 1:dt3){
  mutate(dt3, role = ifelse( dt3$name [[n,i]] == dt3$name[[n,1]] &  
        dt3$birth_year[[n,i]] > dt3$birth_year[[n,1]],"children","NoA"))
  }

我正在探索的两种解决方案都没有成功,我期待的是这样的结果:

birth_year       Name           role        hh

1877        Snijders    Head ofhousehold    1
1885        Marteen     NA                  1
1897        Snijders    children            1
1892        Zelstra     NA                  1
1878        Kuipers     Head of household   2
1870        Marteen     NA                  2
1897        Wals        NA                  2
1900        Venstra     NA                  2
1900        Lippe       Head of household   3
1905        Flachs      NA                  3
1920        Lippe       children            3
1922        Lippe       children            3

欢迎任何提示。

先感谢您

标签: rlistloopsif-statementdplyr

解决方案


也许以下更快:

您可以先按 hh 和 role!="HeadOfHousehold" 排序,这会将 head 角色放在每个家庭的第一行,您已经做过但可能以不同的方式,然后使用aveper hh 测试名称是否相等并且birth_year 的差异大于 14

dt3 <- read.table(header=T, text="birth_year      Name           role        hh
1877        Snijders    HeadOfHousehold    1
1885        Marteen     NA                  1
1897        Snijders    NA                  1
1892        Zelstra     NA                  1
1878        Kuipers     HeadOfHousehold   2
1870        Marteen     NA                  2
1897        Wals        NA                  2
1900        Venstra     NA                  2
1900        Lippe       HeadOfHousehold   3
1905        Flachs      NA                  3
1920        Lippe       NA                  3
1922        Lippe       NA                  3", as.is = T)

dt3 <- dt3[with(dt3, order(hh,role!="HeadOfHousehold")),]
dt3$role[with(dt3, as.logical(ave(Name, hh, FUN = function(x) x==x[1])) & ave(birth_year, hh, FUN = function(x) x>(x[1]+14)))] <- "children"
dt3

   birth_year     Name            role hh
1        1877 Snijders HeadOfHousehold  1
2        1885  Marteen            <NA>  1
3        1897 Snijders        children  1
4        1892  Zelstra            <NA>  1
5        1878  Kuipers HeadOfHousehold  2
6        1870  Marteen            <NA>  2
7        1897     Wals            <NA>  2
8        1900  Venstra            <NA>  2
9        1900    Lippe HeadOfHousehold  3
10       1905   Flachs            <NA>  3
11       1920    Lippe        children  3
12       1922    Lippe        children  3

推荐阅读