首页 > 解决方案 > 运行循环,将 if else 条件应用于数据框的子集(或完整的数据框)

问题描述

我有以下问题:我需要运行数据框的每个子集,根据 2 个条件为变量角色创建新条目:证人姓名和家庭居民姓名之间的匹配。

数据框 (df) 如下:我有 10 个变量(IDbirth_year、姓氏 -<strong>Name2nd-、家庭中的角色 -角色-、家庭-hh -、名字 -<strong>Name1st-、第一证人 1 的姓名 - name1stW1 -,证人 1 的姓氏 - name2ndW1 -,与 ID 的关系以及与 ID 配偶的关系 -<strong>relation2-)。

整个表由hh变量子集,收集同一家庭下的所有 ID。最后四个变量显示 ID 婚姻中第一个见证人的姓名,以及他们与该 ID 的关系 -关系- 以及与他们的配偶 -<strong>relation2-。例如,在下面的示例中,ID 1 是Albert Snijders,其婚礼见证人是Kornelis MarteenKornelis Marteen是他的兄弟(关系)和配偶的姐夫(关系2 )。

现在在这里,由于Kornelis Marteen也和 ID 1 住在同一个家庭,我们知道 ID 1 和 2 之间的关系,我需要将变量角色的值从 NA 更改为“brother-brother in law”(在其他也就是说,对于两个关系的组合值:relation - relation2 )。

ID  birth_year    Name2nd           role        hh    Name1st name2ndW1 name1stW1 relation relation2
1    1877        Snijders    HeadOfHousehold     1     Albert    Marteen   Kornelis  brother brother-in-law
2    1885        Marteen     NA                  1     Kornelis  NA        NA         NA     NA
3    1897        Snijders    NA                  1     Marja     NA        NA         NA     NA
4    1892        Zelstra     NA                  1     Inge      NA        NA         NA     NA
5    1878        Kuipers     HeadOfHousehold     2     Hans      Snijders  Marja      friend friend
6    1870        Marteen     NA                  2     Joris     Marteen   Joris      NA     NA    
7    1897        Wals        NA                  2     Michel    NA        NA         NA     NA
8    1900        Venstra     NA                  2     Joop      NA        NA         NA     NA
9    1900        Lippe       HeadOfHousehold     3     Jaap      NA        NA         NA     NA
10   1905        Flachs      NA                  3     Klaas     Alb       Kuipers    NA     NA
11   1920        Lippe       NA                  3     Mathias   NA        NA         NA     NA
12   1922        Lippe       NA                  3     Waltfried Flachs    Klaas    cousin   cousin     

您可以通过以下方式获取表格:

A <- read.table(header=T, text="ID  birth_year    Name2nd           role             hh    Name1st name2ndW1 name1stW1 relation relation2
                                1    1877        Snijders    HeadOfHousehold          1     Albert    Marteen   Kornelis  brother brother-in-law
                                2    1885        Marteen     NA                       1     Kornelis  NA        NA         NA     NA
                                3    1897        Snijders    NA                       1     Marja     NA        NA         NA     NA
                                4    1892        Zelstra     NA                       1     Inge      NA        NA         NA     NA
                                5    1878        Kuipers     HeadOfHousehold          2     Hans      Snijders  Marja      friend friend
                                6    1870        Marteen     NA                       2     Joris     Marteen   Joris      NA     NA    
                                7    1897        Wals        NA                       2     Michel    NA        NA         NA     NA
                                8    1900        Venstra     NA                       2     Joop      NA        NA         NA     NA
                                9    1900        Lippe       HeadOfHousehold          3     Jaap      NA        NA         NA     NA
                                10   1905        Flachs      NA                       3     Klaas     Kuipers   Alb        NA     NA
                                11   1920        Lippe       NA                       3     Mathias   NA        NA         NA     NA
                                12   1922        Lippe       NA                       3     Waltfried Flachs    Klaas  cousin  cousin  "    
                  , as.is = T)

到了这里,我有两个问题。我试图做的是按家庭(hh)进行聚类,如果家庭中的任何成员碰巧也是任何家庭成员婚姻的见证人,那么修改他们角色的价值(对于那些出现在关系变量中的人) .

我想到了ddply:

df <- ddply(df,.(hh),transform,role = ifelse((name2ndW1==Name2nd & name1stW1==Name1st),paste(relatie-relatie2),NA))

但这不起作用。我在“角色”方面没有任何变化。这是我主要关心的问题。

我的第二个问题(不是那么重要)是针对我决定不针对每个子集(hh)执行此ifelse测试的情况,而是针对整个数据集。有没有与上面类似的代码

df <- ddply(df,.(),transform,role = ifelse((name2ndW1==Name2nd & name1stW1==Name1st),paste(relatie-relatie2),NA))

没有分组变量

我的预期结果是:

ID  birth_year    Name2nd           role             hh    Name1st name2ndW1 name1stW1 relation relation2
1    1877        Snijders    HeadOfHousehold          1     Albert    Marteen   Kornelis  brother brother-in-law
2    1885        Marteen     brother-brother-in-law   1     Kornelis  NA        NA         NA     NA
3    1897        Snijders    NA                       1     Marja     NA        NA         NA     NA
4    1892        Zelstra     NA                       1     Inge      NA        NA         NA     NA
5    1878        Kuipers     HeadOfHousehold          2     Hans      Snijders  Marja      friend friend
6    1870        Marteen     NA                       2     Joris     Marteen   Joris      NA     NA    
7    1897        Wals        NA                       2     Michel    NA        NA         NA     NA
8    1900        Venstra     NA                       2     Joop      NA        NA         NA     NA      
9    1900        Lippe       HeadOfHousehold          3     Jaap      NA        NA         NA     NA
10   1905        Flachs      cousin-cousin            3     Klaas     Kuipers   Alb        NA     NA
11   1920        Lippe       NA                       3     Mathias   NA        NA         NA     NA
12   1922        Lippe       NA                       3     Waltfried Flachs    Klaas    cousin  cousin   

欢迎任何提示,非常感谢您的阅读。

标签: r

解决方案


这是一个解决方案,使用 packagedplyr而不是plyr. 诀窍是将表与自身的副本连接起来,将人名映射到见证人姓名。为了更清楚,我创建了df_witness,它是A重命名字段的副本(子集)

library(dplyr)
df_witness = A %>%
  select(hh, Name1st=name1stW1, Name2nd=name2ndW1, i_rel=relation, i_rel2=relation2) %>% 
  filter(!is.na(Name2nd))

A %>% 
  left_join(
    df_witness, 
    by = c("hh", "Name1st", "Name2nd")
    ) %>% 
  mutate(role = if_else(!is.na(role), role, paste0(i_rel,"-",i_rel2))) %>% 
  select(-i_rel, -i_rel2)

如果您想在整个数据集中而不是仅在家庭中搜索见证人,您可以加入(并从 中by = c("Name1st", "Name2nd")删除变量)hhdf_witness


推荐阅读