Заменить содержимое столбца факторов в R-файле
Мне нужно заменить уровни столбца факторов в кадре данных. Используя dataset iris
в качестве примера, как заменить любые ячейки, которые содержат virginica
с setosa
в столбце Species ?
Я ожидал, что следующее будет работать, но оно генерирует предупреждающее сообщение и просто вставляет NA:
iris$Species[iris$Species == 'virginica'] <- 'setosa'
- Как автоматически включить все двухсторонние взаимодействия в модели glm в R
- cbind a df с пустым df (cbind.fill?)
- Вычислить разницу между значениями в последовательных строках по группам
- Интерпретация "имеет длину> 1" предупреждение от функции `if`
- добавление NA, чтобы все элементы списка равны длине
- найти все функции (включая частные) в пакете
- Извлечение строк для первого вхождения переменной в фрейм данных
- R применяется с несколькими параметрами
- Как подсчитать количество уникальных значений по группе?
- Сплит-кадр данных по уровням фактора и именных кадров данных по этим уровням
- Определить все объекты данного classа для дальнейшей обработки
- Изменение имени переменной в цикле for с использованием R
- Использование R для отображения всех файлов с указанным расширением
Бьюсь об заклад, проблема заключается в том, что вы пытаетесь заменить значения на новую, которая в настоящее время не является частью уровней существующего фактора:
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'
Для вещей, которые вы предлагаете, вы можете просто изменить уровни, используя levels
:
levels(iris$Species)[3] <- 'new'
Вы можете использовать функцию revalue
из пакета plyr
для замены значений в векторе факторов.
В вашем примере заменить фактор virginica
на setosa
:
data(iris) library(plyr) revalue(iris$Species, c("virginica" = "setosa")) -> iris$Species
У меня такая же проблема. Это работало лучше:
Определите, какой уровень вы хотите изменить: levels(iris$Species)
"setosa" "versicolor" "virginica"
Итак, setosa
– первая.
Затем напишите:
levels(iris$Species)[1] <-"new name"
Более общее решение, которое работает со всем фреймом данных сразу и где вам не нужно добавлять новые уровни факторов, является:
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"
, а новые значения могут быть случайными. Таким образом, вы можете создать полный новый случайный кадр данных с тем же размером, что и оригинал.
Использование 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
-1 setosa 50 2 Versicolor 50 3 Virginica 50 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
1 setosa 50 2 Versicolor 50 3 Virginica 50
Если вам нужно заменить несколько значений, и если вы не возражаете «рефакторинг» своей переменной с помощью 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))