由多个条件子集

时间:2014-03-18 09:32:01

标签: r subset

也许这是基本的东西,但我找不到答案 我有

Id Year V1  
 1 2009 33   
 1 2010 67  
 1 2011 38  
 2 2009 45  
 3 2009 65  
 3 2010 74  
 4 2009 47  
 4 2010 51  
 4 2011 14

我只需要选择具有相同Id但在2009年,2010年和2011年三年内的行。

Id Year V1  
 1 2009 33  
 1 2010 67  
 1 2011 38  
 4 2009 47  
 4 2010 51  
 4 2011 14   

我试试

d1_3 <- subset(d1, Year==2009 |Year==2010 |Year==2011 )

但它不起作用。

任何人都可以提供一些建议,告诉我如何在R中做到这一点吗?

4 个答案:

答案 0 :(得分:4)

我认为ave在这里很有用。我将原始数据框称为“df”。对于每个Id,请检查年份(2009:2011 %in% x)中是否存在2009-2011。这给出了一个逻辑向量,可以是sum med。测试总和是否等于3(如果所有年份都存在,总和为3),这将产生一个新的逻辑向量,用于对数据帧的行进行子集化。

df[ave(df$Year, df$Id, FUN = function(x) sum(2009:2011 %in% x) == 3, ]
#   Id Year V1
# 1  1 2009 33
# 2  1 2010 67
# 3  1 2011 38
# 7  4 2009 47
# 8  4 2010 51
# 9  4 2011 14

答案 1 :(得分:2)

这应该做的工作:)

library(plyr)
ds<-ddply(ds,.(Id),mutate,Nobs=length(Year))
ds[ds$Nobs == 3 & ds$Year %in% 2009:2011,]

答案 2 :(得分:2)

使用ave

的另一种方法
DF
##   Id Year V1
## 1  1 2009 33
## 2  1 2010 67
## 3  1 2011 38
## 4  2 2009 45
## 5  3 2009 65
## 6  3 2010 74
## 7  4 2009 47
## 8  4 2010 51
## 9  4 2011 14


DF[ave(DF$Year, DF$Id, FUN = function(x) all(2009:2011 %in% x)) == 1, ]
##   Id Year V1
## 1  1 2009 33
## 2  1 2010 67
## 3  1 2011 38
## 7  4 2009 47
## 8  4 2010 51
## 9  4 2011 14

答案 3 :(得分:1)

我认为使用ave的方法是合理的。但是有很多方法可以解决这个问题。我使用基础R展示了一些其他方法。然后在最后两个示例中,我将介绍包data.table

再次,只是把它扔到那里提供一些选项来使用该语言的不同方面。

d1 <- data.frame(ID=c(1,1,1,2,3,3,4,4,4), Year=c(2009,2010,2011, 2009,2009, 2010, 2009, 2010, 2011), V1=c(33, 67, 38, 45, 65, 74, 47, 51, 14))


# long way
use_years <- as.character(2009:2011)
cnts <- table(d1[,c("ID","Year")])[,use_years]
use_id <- rownames(cnts)[rowSums(cnts)==length(use_years)]
d1[d1[,"ID"]%in%use_id,]
# 1  1 2009 33
# 2  1 2010 67
# 3  1 2011 38
# 7  4 2009 47
# 8  4 2010 51
# 9  4 2011 14

# another longish way
ind1 <- d1[,"Year"]%in%2009:2011
d1_ind <- d1[ind1,"ID"]
ind2 <- d1_ind %in% unique(d1_ind)[tabulate(d1_ind)==3]
d1[ind1,][ind2,]
#   ID Year V1
# 1  1 2009 33
# 2  1 2010 67
# 3  1 2011 38
# 7  4 2009 47
# 8  4 2010 51
# 9  4 2011 14

好的,让我们尝试使用data.table的几种方法。我最喜欢的包装之一。起初可能有点棘手,所以要确保你的靴子紧张(哦,是的,它快!)

# medium way
library(data.table)
d2 <- as.data.table(d1)

d2[ID%in%d2[Year%in%2009:2011, list(logic=nrow(.SD)==3),by="ID"][(logic),ID]]
#    ID Year V1
# 1:  1 2009 33
# 2:  1 2010 67
# 3:  1 2011 38
# 4:  4 2009 47
# 5:  4 2010 51
# 6:  4 2011 14


# short way
d2[Year%in%2009:2011][ID%in%unique(ID)[table(ID)==3]]
#    ID Year V1
# 1:  1 2009 33
# 2:  1 2010 67
# 3:  1 2011 38
# 4:  4 2009 47
# 5:  4 2010 51
# 6:  4 2011 14