R 中的灵活子集 data.table

Flexible subseting data.table in R

我正在处理人口普查数据。 Data-set 如下所示:它是一组用 Id 标识的家庭(或家庭),每个家庭成员都有一个 Id.in.HH。每个家庭都有一个负责人。家庭中的每个实体都有一个 relation 到户主 [1 表示户主,2 表示户主的配偶,3 表示户主的 child]。例如,Id == 1 的家庭有 4 个成员,Id.in.HH 的成员从 1 到 4 不等。这个家庭有一个头 [Id == 1 & Id.in.HH == 3],从它的 Relation.to.Head 值 [Relation.to.Head == 1]。等等。 Gender 有两个值 [1: male2: female]。 Data-set 来自允许男性一夫多妻制的国家。我想添加一个计算 family Type 的列。如果是男主一妻的家庭[Type := 1],如果是女主一夫的家庭[Type:= 2],如果是男主多妻的家庭[Type:= 3]。对于每个孩子,都会记录 her/his 母亲的 Id.In.HH。我想添加一个包含 her/his 母亲生日的列。我正在与 data.table 一起工作,但我是业余爱好者。

Id  Id.in.HH  Relation.to.Head  Gender  Mother.Id.In.HH Birth
1   1         2                 1       NA              1950
1   2         3                 2       3               1975
1   4         3                 2       3               1980
1   3         1                 2       NA              1955
2   2         1                 1       NA              1943             
2   3         2                 2       NA              1945        
2   1         2                 2       NA              1960     
2   5         3                 1       3               1964
2   4         3                 2       1               1980        
3   2         1                 1       NA              1975      
3   3         2                 2       NA              1977    
3   1         3                 1       3               1994         

我希望它看起来像:

Id  Id.in.HH  Relation.to.Head  Gender  Mother.Id.In.HH Birth  Type  Mom.Birth
1   1         2                 1       NA              1950   2     NA
1   2         3                 2       3               1975   2     1955
1   4         3                 2       3               1980   2     1955
1   3         1                 2       NA              1955   2     NA
2   2         1                 1       NA              1943   3     NA           
2   3         2                 2       NA              1945   3     NA 
2   1         2                 2       NA              1960   3     NA
2   5         3                 1       3               1964   3     1945
2   4         3                 2       1               1980   3     1960    
3   2         1                 1       NA              1975   1     NA         
3   3         2                 2       NA              1977   1     NA
3   1         3                 1       3               1994   1     1977 

我试过@jlhoward 的解决方法:

familyType <- function(relation, gender) {
  polygamy = sum(relation == 2, na.rm = TRUE)
  headgender = gender[relation == 1]
  polygamy = as.integer(levels(polygamy))[polygamy]
  headgender = as.integer(levels(headgender))[headgender]
  if(polygamy == 0) {
    if(headgender == 1){
      return (1L)
    } else {
      return (2L)
    }
  } else if(polygamy == 1){
    if(headgender == 1){
      return (3L)
    } else {
      return (4L)
    }
  } else if(polygamy > 1) {
    return (5L)
  }
}

tbl[, type:=familyType(Relation.to.Head, Gender), by=Id]

但是我得到了这个错误:

Error in if (polygamy == 0) { : missing value where TRUE/FALSE needed

真的是两个问题。这是第一部分。

get.type <- function(relation,gender) {
  if (sum(relation==2)>1) return(3L)
  gender[relation==1]
}
DT[,Type:=get.type(Relation.to.Head,Gender), by=Id]

第二部分使用@PierreLafortune 的出色方法:

DT[, Mom.Birth := Birth[match(Mother.Id.In.HH, Id.in.HH)], by=Id]
DT
#     Id Id.in.HH Relation.to.Head Gender Mother.Id.In.HH Birth Type Mom.Birth
#  1:  1        1                2      1              NA  1950    2        NA
#  2:  1        2                3      2               3  1975    2      1955
#  3:  1        4                3      2               3  1980    2      1955
#  4:  1        3                1      2              NA  1955    2        NA
#  5:  2        2                1      1              NA  1943    3        NA
#  6:  2        3                2      2              NA  1945    3        NA
#  7:  2        1                2      2              NA  1960    3        NA
#  8:  2        5                3      1               3  1964    3      1945
#  9:  2        4                3      2               1  1980    3      1960
# 10:  3        2                1      1              NA  1975    1        NA
# 11:  3        3                2      2              NA  1977    1        NA
# 12:  3        1                3      1               3  1994    1      1977
library(dplyr)

family.head_gender =
  person %>%
  filter(Relation.to.Head == 1) %>%
  select(Id, head_gender = Gender)

family.type = 
  person %>%
  filter(Relation.to.Head == 2) %>%
  group_by(Id) %>%
  summarize(number_of_spouses = n() ) %>%
  left_join(family.head_gender) %>%
  mutate(type = 
           ifelse(head_gender == 1,
             ifelse(number_of_spouses = 1,
               1,
               3),
             2)) %>%
  select(-head_gender, -number_of_spouses)

person.final = 
  person %>%
  left_join(
    person %>%
    select(Mother.Id.In.HH = Id.In.HH,
           Mom.Birth = Birth) ) %>%
  left_join(family.type)