Переименовать один уровень фактора в R

Я пытаюсь переименовать уровень A фактора column1 в кадре данных df в R. Мой текущий подход таков:

levels(df[!is.na(df$column1) & df$column1 == 'A',]) <- 'B'

который не выдает никаких ошибок или предупреждений, но совершенно неэффективен.

B не является уже существующим уровнем (который методом проб и ошибок я подозревал, что он важен), поэтому следующая моя первая попытка тоже не сработала

df[!is.na(df$column1) & df$column1 == 'A', 'column1'] <- 'B'

Может ли кто-нибудь указать мне правильный подход?


person perilousGourd    schedule 29.04.2015    source источник


Ответы (2)


я собирался предложить

levels(df$column1)[levels(df$column1)=="A"] <- "B"

или используйте служебную функцию plyr::revalue:

library("plyr")
df <- transform(df,
          column1=revalue(column1,c("A"="B")))

transform() — это немного сахара, в котором нет необходимости; вы могли бы использовать df$column1 <- revalue(df$column1(...))

Для полноты car::recode также работает, хотя я нахожу его немного более неуклюжим, чем plyr::revalue (поскольку перекодировка указана как строка в кавычках).

car::recode(df$column1,"'A'='B'")
person Ben Bolker    schedule 29.04.2015
comment
Это лучшее, что я тоже мог придумать. Это один из тех случаев, когда индексация R действительно не очень аккуратна. - person thelatemail; 29.04.2015

Одним из способов было бы просто изменить метку уровня. Сначала немного тестовых данных

df <- data.frame(column1=c("A","B","C","A","B"))

а теперь заменим "А" на "Х"

levels(df$column1) <- gsub("A","X", levels(df$column1))

и мы видим, что он изменился

  column1
1       X
2       B
3       C
4       X
5       B

Возможно, вам придется быть осторожным с gsub(), так как он принимает регулярное выражение. Более конкретной заменой будет

gsub("^A$","X", levels(df$column1))

чтобы соответствовать именно "A", а не "CAB" или что-то еще с большой буквы.

person MrFlick    schedule 29.04.2015
comment
gsub здесь немного рискованно. Что, если бы у вас были уровни A и Ajax? - person thelatemail; 29.04.2015
comment
@thelatemail я редактировал, как вы прокомментировали. - person MrFlick; 29.04.2015