我有以下问题:我需要运行一个数据帧的每个子集-基于变量的值-根据2个条件为另一个变量创建一个新条目。
数据帧(dt3)如下:我有4个变量(出生年,姓–名称-,在家庭中的角色-角色-和家庭-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变量
分割dt3dt3 <- 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
欢迎任何提示。
提前谢谢
答案 0 :(得分:1)
您可以先提取所有“ HeadOfHousehold”,然后将它们合并到您的dt3
中,然后对姓名和出生年份进行比较。
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)
tt <- with(dt3[!is.na(dt3$role) & dt3$role=="HeadOfHousehold",], data.frame(a=birth_year, b=Name, hh))
me <- merge(dt3, tt, all.x=T)
me$role[me$Name==me$b & me$birth_year > me$a+14] <- "children"
me[names(dt3)]
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
答案 1 :(得分:1)
您也可以简单地使用for循环,例如:
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")),]
for(i in 1:nrow(dt3)) {
if(!is.na(dt3$role[i]) & dt3$role[i] == "HeadOfHousehold") {
hh <- dt3$hh[i]
Name <- dt3$Name[i]
birth_year <- dt3$birth_year[i]
} else {
if(hh == dt3$hh[i] & Name == dt3$Name[i] & dt3$birth_year[i] > birth_year+14) {dt3$role[i] <- "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
答案 2 :(得分:0)
也许以下速度更快:
您可以先通过hh和role!=“ HeadOfHousehold”进行订购,该操作将head角色放置在每个家庭的第一行中,您已经做过的事情,但可能以其他方式做了,然后用{{1} } / hh(如果名称相同,并且birth_year的差异大于14
ave