2014-03-02 25 views
4

我在R.不平衡面板数据下面将作为一个例子:一个子集不平衡面板的数据集具有作为R至少2个连续的观测

dt <- data.frame(name= rep(c("A", "B", "C"), c(3,2,3)), 
       year=c(2001:2003,2000,2002,2000:2001,2003)) 

> dt 
    name year 
1 A 2001 
2 A 2002 
3 A 2003 
4 B 2000 
5 B 2002 
6 C 2000 
7 C 2001 
8 C 2003 

现在,我需要有至少2连续year观察每个name。因此,我想删除第4,5和8行。我如何在R中最好地做到这一点?

编辑: 由于下面的评论,我可以更清楚一点。如果我有一个额外的观察(第9行)与name = Cyear = 2004,我想保持行8和9连同其他行。

+2

如果什么行9包含'C 2004'的解决方案?你会想保留它,并排第8? –

+0

如果你有这个名字:'2000,2002,2003,2005,2007,2008'?你应该保留“2002,2003,2007,2008”吗?如果是这样,那将导致非连续的年份。那是对的吗? –

+0

@ JoshO'Brien是的。 – Mace

回答

4

我(的hackish)的方式来做到这一点是:

is.consecutive = duplicated(rbind(dt,transform(dt, year=year+1), 
            transform(dt, year=year-1)), 
          fromLast=TRUE)[1:nrow(dt)] 

is.consecutive包含观测布尔值的矢量被保留。对于你的例子,这个向量应该是:TRUE TRUE TRUE FALSE FALSE TRUE TRUE FALSE

最后,你可以很容易地使用这个向量来对你的数据进行子集化。与:

dt[is.consecutive,] 
+0

感谢您的回答!它需要排序的名称,年份,对吗? – Mace

+0

一点都不:这两个变量都可以随机排列:) – Jealie

+0

啊,是啊 - 现在我明白了...... – Mace

4

这是一个更多(太... ...)错综复杂的替代方案,您可以设置连续观测运行的最小长度。

dt <- dt[order(dt$name, dt$year), ] 

rl <- 2 

do.call(rbind, 
     by(dt, dt$name, function(x){ 
      run <- c(0, cumsum(diff(x$year) > 1)) 
      x[ave(run, run, FUN = length) >= rl, ] 
     }) 
) 
#  name year 
# A.1 A 2001 
# A.2 A 2002 
# A.3 A 2003 
# C.6 C 2000 
# C.7 C 2001 

rl <- 3 

do.call(rbind, 
     by(dt, dt$name, function(x){ 
      run <- c(0, cumsum(diff(x$year) > 1)) 
      x[ave(run, run, FUN = length) >= rl, ] 
     }) 
) 
#  name year 
# A.1 A 2001 
# A.2 A 2002 
# A.3 A 2003 
3

这里使用ddply

library(plyr) 
ddply(dt,"name",function(x) { 
    cons_idx=which(diff(x$year)==1) 
    cons_idx=sort(unique(c(cons_idx,cons_idx+1))) 
    x[cons_idx,] 
}) 
相关问题