2016-12-27 33 views
0

每当至少有一个来自该组的主题满足两个条件时,我试图从数据库中识别(使用二进制1/0变量)主体组。如果在其中一个条件发生时识别个人组

我的数据库DF由随性的描述和年龄每个成员的(和家庭ID family)的家庭:我想创建一个新的二元变量NoMan这将是0,如果从男性的至少一个一个家庭(sx与属性1)是年龄更多比16年,否则它将取值1.请注意,我想NoMan是来自同一家庭的所有成员相同。

family <- factor(rep(c("001","002","003"), c(10,8,15)), 
       levels=c("001","002","003"), labels=c("001","002","003"), ordered=TRUE) 
ag <- c(22,8,4,2,55,9,44,65,1,7,32,2,2,1,6,9,18,99,73,1,2,3,4,5,6,7,8,9,10,18,11,22,33) 
sx <- c(1,2,2,2,1,2,2,2,1,1,2,1,2,1,2,1,2,2,2,2,1,2,1,2,1,2,1,2,1,2,1,2,2) 
DF <- data.frame(family, ag, sx) 
DF 

我曾尝试使用ddplyifelse合并,但这并不成功:

DF <- ddply(DF,.(family), transform, NoMan=ifelse(sx==1 & ag>16, 1, 0)) 
DF 

看来,中最终其他的限制,在这个脚本的功能,适用于我个人,而不是家庭(实际上希望他们将同样的结果应用于同一家庭的所有成员)。

我觉得我在正确的轨道上,但也许有人有一个很好的解决这个问题?

PS:刚编辑DF,因为在这个例子中,我想从家庭003所有成员被标记为NoMan==1

+0

谢谢乌韦座 – den

+0

正如你已经改变了Q,所有的答案 - 尤其是_S面包车Balen_接受一个 - 应该修改我猜也是。 – Uwe

+0

事实上,Uwe Block,我的错误......年龄的条件应该都是'ag> 16''。大多数答案在这里工作得很好。谢谢 – den

回答

1
DF$NoMan = c(! DF$family %in% unique(DF[DF$sx == 1 & DF$ag < 16,1])) 
+0

这也行得通!谢谢 – den

+0

我喜欢em在一行;)这样可以为你节省一个资源库。 –

1

ifelse返回结果的矢量无视组,您可以使用any聚集每组的结果:

library(plyr) 
ddply(DF, .(family), transform, NoMan = +any(sx == 1 & ag < 16)) 
+0

谢谢,但是使用这个我只是'1'作为'NoMan'的值:我们应该如'ifelse'中指定条件的结果吗?恩。何时取值0,何时取值1?谢谢! – den

+0

这取决于你希望你的数据是如何。该逻辑基于*二元变量NoMan,如果至少有一个来自家庭的男性(属性为1的sx)小于16y *,则该值为0。当然,对于您的样本数据,所有家庭至少包含一名年龄小于16岁的男性。您的描述与您的代码不同。也许你想'ddply(DF,。(family),transform,NoMan = +!any(sx == 1&ag <16))' – Psidom

+0

对不起!你是对的,我已经改变了这个数据,这应该与新的'DF'现在工作? ..但我仍然只得到1作为输出(或从您的上一个脚本0)。 – den

1

我们可以使用dplyr

library(dplyr) 
DF %>% 
    group_by(family) %>% 
    mutate(NoMan = as.integer(any(sx == 1 & ag < 16))) 

或者使用avebase R

DF$NoMan <- with(DF, as.integer(ave(sx==1 & ag < 16, family, FUN = any))) 
+0

谢谢,但是这个拳头解决方案没有工作,当我尝试。你的第二个解决方案工作正常,但二进制变量值(0而不是1,反之亦然) – den

+0

@den我使用了'dplyr_0.5.0'并且它正在为我工​​作。关于第二种解决方案,如果你需要相反的话,只要用(DF,as)。整数(!ave(sx == 1&ag <16,family,FUN = any)))'或更改条件 – akrun

+1

Great!'DF $ NoMan < - with(DF,as.integer(!ave(sx == 1&ag> 16,family,FUN = any)))'工作正常 – den

1
#Obtain unique families 
family = c(unique(as.character(DF$family))) 
NoMan = c() 

for (i in 1:length(family)){ 
#Subset a new dataframe for each family with only male members and check if minimun age is below 16 
if (min(subset(DF,DF$family == family[1] & DF$sx=="1")$ag) < 16){ 
NoMan[i] = 1 
} else { 
NoMan[i] = 0 
} 
} 

#Join unique family and NoMan into new dataframe 
DF2 = cbind(family,NoMan) 

#Use lookup command of qdapTools package 
library(qdapTools) 
DF$NoMan = lookup(DF$family,DF2) 
相关问题