2015-07-28 8 views
2

У меня есть фактор-фактор. Некоторые значения могут быть повторены. Значения не известны заранее, но могут быть отсортированы. Например,R: эффективный способ присвоения уровней факторов

x1 <- factor(c("A", "C", "C", "A", "B"), levels=c("A", "B", "C")) 
x2 <- factor(c("E", "C", "C", "D", "B"), levels=c("B", "C", "D", "E")) 

Я хочу, чтобы создать еще один вектор, в котором каждое значение является либо «последний», «другое» или «первый», а значения соответствуют первому или последнему уровню фактора. В приведенном выше случае результирующий вектор y1 должен быть равен c("first", "last", "last", "first", "other"), тогда как y2 должен быть равен c("last", "other", "other", "other", "first").

В настоящее время я делаю это так:

f2l <- function(x) { 
    x <- as.numeric(x) 
    y <- rep("other", length(x)) 
    y[ x == max(x) ] <- "last" 
    y[ x == min(x) ] <- "first" 
    y 
} 

Это работает, как задумано, но мне интересно, есть ли более эффективное решение.

+0

вы можете рассмотреть своего рода слияние с использованием 'data.table' [_a LA_] (http://stackoverflow.com/questions/28181753/grouping-factor-levels-in -an-р-данных таблицы) – MichaelChirico

ответ

3

Вы можете переназначить метки уровня с помощью списка.

x1 <- factor(c("A", "C", "C", "A", "B"), levels=c("A", "B", "C")) 
x2 <- factor(c("E", "C", "C", "D", "B"), levels=c("B", "C", "D", "E")) 

f2l <- function(x){ 
    levels(x) <- list("first" = levels(x)[1], 
        "other" = levels(x)[-c(1, nlevels(x))], 
        "last" = levels(x)[nlevels(x)]) 
    x 
} 

f2l(x1) 
f2l(x2) 
1

Помимо метода Беньямина, если вы уверены, что число уровней будет больше, чем 2, вы можете использовать

f2l <- function(x){ 
    levels(x) <- c("first",rep("other",length(levels(x))-2),"last"); 
    x 
} 

Если вы делаете это для многих factors тогда метод Бенджамина медленно по сравнению с указанным выше способом. Время для 100000 повторений

Benjamin 
user system elapsed 
26.58 0.00 26.68 

Saksham 
user system elapsed 
17.15 0.08 18.30 
Смежные вопросы