49

I need to replace the levels of a factor column in a dataframe. Using the iris dataset as an example, how would I replace any cells which contain virginica with setosa in the Species column?

I expected the following to work, but it generates a warning message and simply inserts NAs:

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

8 回答 8

102

我敢打赌,问题在于当您尝试用新值替换值时,该值当前不属于现有因素的水平:

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'

如果你想用“species B”替换“species A”,你最好用

levels(iris$Species)[match("oldspecies",levels(iris$Species))] <- "newspecies"
于 2012-08-04T17:51:03.063 回答
20

对于您建议的事情,您可以使用以下方法更改级别levels

levels(iris$Species)[3] <- 'new'
于 2012-08-04T22:10:47.243 回答
11

您可以使用revalue包中的函数plyr来替换因子向量中的值。

在您的示例中,将因子替换virginicasetosa

 data(iris)
 library(plyr)
 revalue(iris$Species, c("virginica" = "setosa")) -> iris$Species
于 2014-01-28T19:29:04.353 回答
5

我有同样的问题。这效果更好:

确定要修改的级别:levels(iris$Species)

    "setosa" "versicolor" "virginica" 

所以,setosa是第一个。

然后,这样写:

     levels(iris$Species)[1] <-"new name"
于 2017-03-23T13:13:54.413 回答
2

使用dlpyr::mutateforcats::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   
于 2018-03-09T14:00:05.403 回答
2

一个更通用的解决方案可以同时处理所有数据框并且您不必添加新的因子水平是:

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",并且新值可以是随机值。因此,您可以创建一个与原始大小相同的全新随机数据框。

于 2018-01-12T15:32:09.430 回答
1

您想替换数据集列中的值,但收到如下错误:

无效因子水平,NA 生成

试试这个:

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

于 2019-01-29T23:04:50.557 回答
0

如果您必须替换多个值,并且您不介意使用 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))
于 2018-03-20T14:15:39.020 回答