2016-11-11 94 views
1

我有這樣對於ID值大於零的所有ID,刪除ID等於零的行。

ID <- c("A","A","A","B","B","C","D") 
Value <- c(0,1,2,0,2,0,0) 
df <- data.frame(ID,Value) 
df 

一個數據幀我想申請,如果有任何ID具有值大於0,那麼我需要刪除ID中的該行與邏輯0

我期望的輸出是

ID Value 
    A  1 
    A  2 
    B  2 
    C  0 
    D  0 

我試圖做這種方式

df <- subset(df,df$Value !=0) 

我知道這是錯誤的,因爲它消除了與0任何ID請就如何解決這個

回答

2

香草方式一些投入幫助:

# get ids with values greater than 0 
delete_zero = unique(subset(df, Value > 0)$ID) 

# delete the rows where the ID is in delete_zero AND the value is 0 
df2 = subset(df, !(ID %in% delete_zero & Value == 0)) 

df2 
# ID Value 
# 2 A  1 
# 3 A  2 
# 5 B  2 
# 6 C  0 
# 7 D  0 

新奇的方式:同一邏輯,但我們做的它dplyr「按組」

library(dplyr) 
df %>% group_by(ID) %>% 
    filter(!(any(Value > 0) & Value == 0)) 

# Source: local data frame [5 x 2] 
# Groups: ID [4] 
# 
#  ID Value 
# <fctr> <dbl> 
# 1  A  1 
# 2  A  2 
# 3  B  2 
# 4  C  0 
# 5  D  0 
+2

或用'all'反轉邏輯和'|':'DF%>%GROUP_BY(ID)%>%濾波器(所有(值== 0 )| Value> 0)' – alistaire

3

你可以使用ave(),首先Value列脅迫邏輯,這樣出來的結果將是子集的矢量使用。我們使用if()語句來確定要保留的值。

df[with(df, ave(as.logical(Value), ID, FUN = function(x) if(any(x)) x else !x)), ] 
# ID Value 
# 2 A  1 
# 3 A  2 
# 5 B  2 
# 6 C  0 
# 7 D  0 

或者與subset()相同。

subset(df, ave(as.logical(Value), ID, FUN = function(x) if(any(x)) x else !x)) 
# ID Value 
# 2 A  1 
# 3 A  2 
# 5 B  2 
# 6 C  0 
# 7 D  0 
2

dplyr方法:

library(dplyr) 
df %>% group_by(ID) %>% filter(if (all(Value==0)) TRUE else Value > 0) 
Source: local data frame [5 x 2] 
Groups: ID [4] 

     ID Value 
    <fctr> <dbl> 
1  A  1 
2  A  2 
3  B  2 
4  C  0 
5  D  0 
+0

True已被回收。無需重複 –