2014-03-02 56 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,] 
}) 
相關問題