2016-12-27 43 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) 
相關問題