Сохранить упорядоченный коэффициент при использовании ddply - PullRequest
3 голосов
/ 13 июля 2011

Я использую 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 изменяет какие столбцы присутствуют, возможно, удаляя упорядоченные факторы.

Мысли?

1 Ответ

3 голосов
/ 13 июля 2011

Я использую приведенный ниже код для этих типов проблем («ddply», а не «упорядоченный фактор»), и кажется, что он обрабатывает ваш конкретный пример без проблем (кроме разных имен строк).

> 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 ...
...