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: male
、2: 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)
我正在处理人口普查数据。 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: male
、2: 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)