Заменить содержимое столбца факторов в R файле

Мне нужно заменить уровни столбца факторов в фрейме данных. Используя в качестве примера набор данных iris, как бы я заменил любые ячейки, которые содержат virginica с setosa в столбце "Виды"?

Я ожидал, что следующее будет работать, но оно генерирует предупреждающее сообщение и просто вставляет NAs:

iris$Species[iris$Species == 'virginica'] <- 'setosa'

Ответ 1

Я уверен, проблема заключается в том, что вы пытаетесь заменить значения на новую, которая не является частью существующих уровней факторов:

levels(iris$Species)
# [1] "setosa"     "versicolor" "virginica" 

Ваш пример был плохим, это работает:

iris$Species[iris$Species == 'virginica'] <- 'setosa'

Это более вероятно создает проблему, которую вы видели своими собственными данными:

iris$Species[iris$Species == 'virginica'] <- 'new.species'
# Warning message:
# In `[<-.factor`(`*tmp*`, iris$Species == "virginica", value = c(1L,  :
#   invalid factor level, NAs generated

Он будет работать, если вы сначала увеличите свои уровни факторов:

levels(iris$Species) <- c(levels(iris$Species), "new.species")
iris$Species[iris$Species == 'virginica'] <- 'new.species'

Ответ 2

Для вещей, которые вы предлагаете, вы можете просто изменить уровни, используя levels:

levels(iris$Species)[3] <- 'new'

Ответ 3

Вы можете использовать функцию revalue из пакета plyr для замены значений в векторе факторов.

В вашем примере заменить коэффициент virginica на setosa:

 data(iris)
 library(plyr)
 revalue(iris$Species, c("virginica" = "setosa")) -> iris$Species

Ответ 4

У меня была та же проблема. Это улучшилось:

Определите, какой уровень вы хотите изменить: levels(iris$Species)

    "setosa" "versicolor" "virginica" 

Итак, setosa является первым.

Затем напишите это:

     levels(iris$Species)[1] <-"new name"

Ответ 5

Более общее решение, которое работает со всеми фреймами данных одновременно, и вам не нужно добавлять новые уровни факторов:

data.mtx <- as.matrix(data.df)
data.mtx[which(data.mtx == "old.value.to.replace")] <- "new.value"
data.df <- as.data.frame(data.mtx)

Приятной особенностью этого кода является то, что вы можете назначить столько значений, сколько у вас есть в исходном фрейме данных, а не только одно "new.value", и новые значения могут быть случайными значениями. Таким образом, вы можете создать совершенно новый случайный фрейм данных того же размера, что и оригинал.

Ответ 6

Использование dlpyr::mutate и forcats::fct_recode:

library(dplyr)
library(forcats)

iris <- iris %>%  
  mutate(Species = fct_recode(Species,
    "Virginica" = "virginica",
    "Versicolor" = "versicolor"
  )) 

iris %>% 
  count(Species)

# A tibble: 3 x 2
     Species     n
      <fctr> <int>
1     setosa    50
2 Versicolor    50
3  Virginica    50   

Ответ 7

Если вам нужно заменить несколько значений и если вы не возражаете против "рефакторинга" вашей переменной с помощью as.factor(as.character(...)), вы можете попробовать следующее:

replace.values <- function(search, replace, x){
  stopifnot(length(search) == length(replace))
  xnew <- replace[ match(x, search) ]
  takeOld <- is.na(xnew) & !is.na(x)
  xnew[takeOld] <- x[takeOld]
  return(xnew)
}

iris$Species <- as.factor(search=c("oldValue1","oldValue2"),
                          replace=c("newValue1","newValue2"),
                          x=as.character(iris$Species))

Ответ 8

Вы хотите заменить значения в столбце набора данных, но вы получаете ошибку, подобную этой:

неверный уровень фактора, сгенерированный NA

Попробуйте это вместо этого:

levels(dataframe$column)[levels(dataframe$column)=='old_value'] <- 'new_value'