2011-07-12 31 views
3

我使用ddply很多。我偶爾使用有序的因素。在包含排序因子的數據幀上調用ddply會丟失重新組合的數據幀中的任何順序。使用ddply時保留有序因子

我寫了下面的包裝爲ddply,記錄水平排序,然後再應用它在原先訂購的任何列:

dat <- data.frame(a=runif(10),b=factor(letters[10:1], 
           levels=letters[10:1],ordered=TRUE), 
        c = rep(letters[1:2],times=5), 
        d = factor(rep(c('lev1','lev2'),times=5),ordered=TRUE)) 

#Drops ordering on b and d  
dat1 <- ddply(dat,.(c),transform,log_a = log(a)) 


ddplyKeepOrder <- function(dat,...){ 
    orderedCols <- colnames(dat)[sapply(dat,is.ordered)] 
    levs <- lapply(dat[,orderedCols,drop=FALSE],levels) 
    result <- ddply(.data = dat,...) 

    ind <- match(orderedCols,colnames(result)) 
    levs <- levs[!is.na(ind)] 
    orderedCols <- orderedCols[!is.na(ind)] 
    ind <- ind[!is.na(ind)] 
    if (length(ind) > 0){ 
     for (i in 1:length(ind)){ 
      result[,orderedCols[i]] <- factor(result[,orderedCols[i]], 
              levels=levs[[i]],ordered=TRUE) 
     } 
    } 
    return(droplevels(result)) 
} 

#Preserves ordering on b and d 
dat2 <- ddplyKeepOrder(dat,.variables = .(c),.fun = transform,log_a = log(a)) 

我還沒有徹底檢查此功能,所以有可能是情況下,不處理。有更好/更完整的方法來處理這個問題嗎?我想,如果我想了一下,我可能會刪除for循環。

特別是,在ddply調用後檢查是否仍然存在任何原始的有序因子看起來真的很難看,但我希望該函數能夠處理哪些情況,其中ddply會改變哪些列是目前,可能會刪除有序的因素。

想法?

+2

想法? ... 錯誤報告。 –

+0

@DWin - 真的,你認爲這是一個錯誤?我沒有看到[github](https://github.com/hadley/plyr)上報告的任何內容(在一個非常快速的檢查中),這似乎太明顯,沒有其他人投訴。 – joran

+0

並不是很多人使用有序的因素。我認爲在不預告的情況下將訂單因素變爲因素是一個錯誤。 –

回答

3

我使用下面的代碼來處理這些類型的問題(「ddply」而不是「ordered factor」),它似乎處理您的具體示例沒有問題(除了不同的行名稱)。

> dat2 <- do.call(rbind, lapply(split(dat, dat$c), transform, log_a=log(a))) 
> str(dat2) 
'data.frame': 10 obs. of 5 variables: 
$ a : num 0.216 0.607 0.197 0.171 0.797 ... 
$ b : Ord.factor w/ 10 levels "j"<"i"<"h"<"g"<..: 1 3 5 7 9 2 4 6 8 10 
$ c : Factor w/ 2 levels "a","b": 1 1 1 1 1 2 2 2 2 2 
$ d : Ord.factor w/ 2 levels "lev1"<"lev2": 1 1 1 1 1 2 2 2 2 2 
$ log_a: num -1.532 -0.499 -1.625 -1.767 -0.227 ... 
+0

是的,我有一種感覺這將是低票。 –

+0

在這種情況下接受答案的SO禮儀是什麼?這個問題的長期價值是可疑的,假設@hadley很快修復了這個bug。刪除問題?讓別人寫一個答案,說明它是一個錯誤並接受它?或者只是讓它成爲? – joran