Подтвердить что ты не робот

Как изменить уровни столбца факторов в таблице данных.

Каков правильный способ изменения уровней столбца factor в data.table (примечание: не фрейм данных)

  library(data.table)
  mydt <- data.table(id=1:6, value=as.factor(c("A", "A", "B", "B", "B", "C")), key="id")

  mydt[, levels(value)]
  [1] "A" "B" "C"

Я ищу что-то вроде:

mydt[, levels(value) <- c("X", "Y", "Z")]

Но, конечно, эта строка не работает.

    # Actual               # Expected result
    > mydt                  > mydt
       id value                id value
    1:  1     A             1:  1     X
    2:  2     A             2:  2     X
    3:  3     B             3:  3     Y
    4:  4     B             4:  4     Y
    5:  5     B             5:  5     Y
    6:  6     C             6:  6     Z
4b9b3361

Ответ 1

Вы все равно можете установить их традиционным способом:

levels(mydt$value) <- c(...)

Это должно быть достаточно быстро, если mydt не очень большой, поскольку этот традиционный синтаксис копирует весь объект. Вы также можете играть в игру без факторинга и рефакторинга... но никто не любит эту игру в любом случае.

Чтобы изменить уровни по ссылке без копирования mydt:

setattr(mydt$value,"levels",c(...))

но обязательно назначьте допустимый вектор уровней (тип character достаточной длины), иначе вы получите недопустимый коэффициент (levels<- выполняет некоторую проверку, а также копирование).

Ответ 2

Я предпочел бы традиционный способ повторного присваивания факторам

> mydt$value # This we what we had originally
[1] A A B B B C
Levels: A B C
> levels(mydt$value) # just checking the levels
[1] "A" "B" "C"
**# Meat of the re-assignment**
> levels(mydt$value)[levels(mydt$value)=="A"] <- "X"
> levels(mydt$value)[levels(mydt$value)=="B"] <- "Y"
> levels(mydt$value)[levels(mydt$value)=="C"] <- "Z"
> levels(mydt$value)
[1] "X" "Y" "Z"
> mydt # This is what we wanted
   id value
1:  1     X
2:  2     X
3:  3     Y
4:  4     Y
5:  5     Y
6:  6     Z

Как вы, вероятно, замечаете, мясо повторного назначения очень интуитивно понятен, он проверяет точный уровень (используйте grepl в случае, если есть нечеткая математика, регулярные выражения или аналогичные)

уровни (значение mydt $) [levels (mydt $value) == "A" ] < - "X" Это явно проверяет значение в "уровнях" рассматриваемой переменной, а затем переназначает "X" (и т.д.) К ней. Преимущество - вы явно ЗНАЕТ, что помечено как.

Я нахожу уровни переименования как здесь уровни (mydt $value) < - c ( "X" , "Y", "Z" ) очень неинтуитивно понятный, поскольку он просто присваивает X 1-й уровень, который он видит в данных (поэтому порядок действительно имеет значение)

PPS: в случае слишком большого количества уровней используйте конструкторы цикла.

Ответ 3

Вы также можете переименовать и добавить свои уровни с помощью соответствующего подхода, который может быть очень удобным, особенно если вы делаете сюжет, который требует более информативных меток в определенном порядке (в отличие от по умолчанию):

f <- factor(c("a","b"))
levels(f) <- list(C = "C", D = "a", B = "b")

(изменено с ?levels)

Ответ 4

Самый простой способ изменить уровни столбцов:

dat$colname <- as.factor(as.vector(dat$colname));