2012-05-24 69 views
0

我有一個家庭列表,以及他們移入新郵政編碼的日期。一小部分如下:跨列的R訂單觀察

ADD0 <- as.Date(c("2008-07-01", "1998-07-01", "2001-11-01", "1997-08-01"), format="%Y-%m-%d") 
ADD1 <- as.Date(c(NA, "2001-09-01", "2002-03-01", NA), format="%Y-%m-%d") 
ADD2 <- as.Date(c(NA, "1992-09-01", "2001-09-01", "2007-12-01"), format="%Y-%m-%d") 
ZIP0 <- as.character(c(30126, 30345, 30068, 30253)) 
ZIP1 <- as.character(c(NA, 30263, 31064, NA)) 
ZIP2 <- as.character(c(NA, 30345, 30067,30062)) 
DF <- data.frame(ADD0, ZIP0, ADD1, ZIP1, ADD2, ZIP2) 
> DF 
     ADD0 ZIP0  ADD1 ZIP1  ADD2 ZIP2 
1 2008-07-01 30126  <NA> <NA>  <NA> <NA> 
2 1998-07-01 30345 2001-09-01 30263 1992-09-01 30345 
3 2001-11-01 30068 2002-03-01 31064 2001-09-01 30067 
4 1997-08-01 30253  <NA> <NA> 2007-12-01 30062 

所以房子2在98年7月,9月'01和9月'92搬家。正如你所看到的,我的問題是日期不一定按照正確的順序,我需要它們。我能看到這樣做的唯一方法是循環訪問數據集並編寫我自己的排序算法,這是我幾乎沒有經驗的。效率也很重要,因爲我有450k的觀察。

以前有人做過這種事嗎?有小費嗎?有沒有我找不到的乾淨解決方案?

+0

**預處理**您的數據一次將其排序到正確的順序有什麼問題?無論如何,你至少必須迭代一次,而排序也是如此便宜。你不需要發明自己的排序算法! –

+0

我不確定你的意思,我在問我如何去預處理我的數據。我不認爲它是一個簡單的排序任務,因爲它通常涉及排序矢量。我相信我接受的答案正是我希望得到的解決方案;你有其他選擇嗎? – gregmacfarlane

回答

1

使用基礎reshape包,我會添加一列house,然後重新整形數據。然後訂購它。

DF$house <- row.names(DF) 
df.long <- reshape(DF, 
        idvar='house', 
        varying=list(c('ADD0', 'ADD1', 'ADD2'), 
           c('ZIP0', 'ZIP1', 'ZIP2')), 
        v.names=c('add', 'zip'), 
        timevar=NULL, 
        direction='long') 
df.long <- df.long[order(df.long$house, df.long$add),] 


    house  add zip 
1.1  1 2008-07-01 30126 
1.2  1  <NA> <NA> 
1.3  1  <NA> <NA> 
2.3  2 1992-09-01 30345 
2.1  2 1998-07-01 30345 
2.2  2 2001-09-01 30263 
3.3  3 2001-09-01 30067 
3.1  3 2001-11-01 30068 
3.2  3 2002-03-01 31064 
4.1  4 1997-08-01 30253 
4.3  4 2007-12-01 30062 
4.2  4  <NA> <NA> 
> 
+1

我真的很喜歡這個解決方案。爲了將它恢復爲分析的其他部分所需的'wide'格式,我在'$ add'向量上使用了'desc()',附加了一個帶有'df.long $ add.num < - sequence( table(df.long $ house))',然後再用'df.wide < - reshape重塑(df.long,idvar =「house」,timevar =「add.num」) – gregmacfarlane

+0

我覺得我也應該提一下除了'reshape'命令(之前我已經使用過)的簡單性之外,我缺少的一點是爲'vary'選項使用'list'。我永遠不會獨立抵達這個地方。 – gregmacfarlane

+0

你也可以在兩個融解步驟中做到這一點。 '熔化(DF,id.var ='house',measure.var = c('ADD0','ADD1','ADD2'),value.name ='add')'然後在房子上合併。但這似乎更笨重。 – Justin

0

一個基於循環的解決方案,可能很慢,但保持您的格式。

DF <- data.frame(ADD0, ZIP0, ADD1, ZIP1, ADD2, ZIP2, stringsAsFactors = F) 
DF2 = DF 

for (i in 1:nrow(DF)){ 
    DF2[i,] = DF[i, 
    rep(order(DF[i,1:(ncol(DF)/2) * 2 -1])*2, each = 2) + (-1:0)] 
} 

我與其他回答者同意雖然。我認爲這裏困難的核心原因是數據存儲在這裏的方式,這是非常無益的工作。

+0

這一步無益於工作;但該過程中的其他步驟要求數據位於單個行上。 – gregmacfarlane