将数据框列的格式从字符型转换为因子型。

189

我想将数据框对象(mydf)的某些列的格式(class)从字符(charactor)改为 因子(factor)

我不想在使用read.table()函数读取文本文件时进行此操作。

任何帮助都将不胜感激。


19
将mydf数据框中的myfavoritecolumn列转换为因子类型。 - tim riffe
谢谢!但我有另一个问题。我有每个列的名称在字符数组col_names[]中。如何使用上面的命令(mydf$col_names[i])不起作用。 - Rasoul
有没有办法自动处理所有字符变量,就像data.frame在stringsAsFactors方面所做的那样? - Etienne Low-Décarie
@EtienneLow-Décarie:只需使用“unclass”并在结果上使用“data.frame”。 - IRTFM
8个回答

241

你好,欢迎来到 R 的世界。

mtcars  #look at this built in data set
str(mtcars) #allows you to see the classes of the variables (all numeric)

#one approach it to index with the $ sign and the as.factor function
mtcars$am <- as.factor(mtcars$am)
#another approach
mtcars[, 'cyl'] <- as.factor(mtcars[, 'cyl'])
str(mtcars)  # now look at the classes

这也适用于字符、日期、整数和其他类。

由于你是R的新手,我建议你看看这两个网站:

R参考手册: http://cran.r-project.org/manuals.html

R参考卡片: http://cran.r-project.org/doc/contrib/Short-refcard.pdf


谢谢!但我有另一个问题。我有每列名称的字符数组 col_names[]。如何使用上述命令(既不是mydf$col_names[i]也不是mydf[,col_names[i]])? - Rasoul
1
@Rasoul,“mydf [,col_names]”将会做这件事。 - DrDom
4
点赞给参考文献。这是基础知识,询问是可以的,但也要知道已经对这些(和类似的)工作进行了广泛的工作。 - Roman Luštrik

102
# To do it for all names
df[] <- lapply( df, factor) # the "[]" keeps the dataframe structure

# to do it for some names in a vector named 'col_names'
col_names <- names(df)
df[col_names] <- lapply(df[col_names] , factor)
解释。所有的数据框都是列表,使用多个值参数的[的结果也是列表,因此循环列表是lapply的任务。上述分配将创建一组列表,函数data.frame.[<-应该可以成功地将其粘贴回数据框df中。
另一种策略是仅转换那些独特项数量小于某个标准的列,例如少于行数的对数:
cols.to.factor <- sapply( df, function(col) length(unique(col)) < log10(length(col)) )
df[ cols.to.factor] <- lapply(df[ cols.to.factor] , factor)

1
这是一个非常好的解决方案!它还可以使用列号,如果您想更改许多但不是全部列,这可能特别有用。例如,col_nums <- c(1, 6, 7:9, 21:23, 27:28, 30:31, 39, 49:55, 57),然后 df[,col_nums] <- lapply(df[,col_nums] , factor)。 - WGray
注意:如果 length(col_names)==1,第一种解决方案将无法正常工作。在这种情况下,df[,col_names] 会自动降级为长度为1的向量,而不是列表,然后 lapply 尝试对每个条目进行操作,而不是整个列。可以通过使用 df[,col_names,drop=FALSE] 来避免这种情况。 - P Schnell
这是一个很好的观点。保留列表状态的另一种调用方法是使用 df[col_names] - IRTFM

36

你可以使用dplyr::mutate_if()将所有字符列转换为因子,或者使用dplyr::mutate_at()选择命名的字符列转换为因子:

library(dplyr)

# all character columns to factor:
df <- mutate_if(df, is.character, as.factor)

# select character columns 'char1', 'char2', etc. to factor:
df <- mutate_at(df, vars(char1, char2), as.factor)

当你有很多列(~50000)并且只需要转换3个时,mutate_at非常快。 - emr2

18

如果你想在加载完数据之后将数据框中的所有字符变量都改成因子变量,可以像这样操作,假设数据框名为dat

character_vars <- lapply(dat, class) == "character"
dat[, character_vars] <- lapply(dat[, character_vars], as.factor)

这创建了一个向量,标识哪些列是character类,然后对这些列应用as.factor

样本数据:

dat <- data.frame(var1 = c("a", "b"),
                  var2 = c("hi", "low"),
                  var3 = c(0, 0.1),
                  stringsAsFactors = FALSE
                  )

每个字符变量完全转换为因子通常发生在读取数据时,例如使用stringsAsFactors = TRUE,但是当您使用readxl包中的read_excel()读取数据并想要训练不接受字符变量的随机森林模型时,这非常有用。 - Sam Firke

14

你可以使用magrittr包中的管道符(%<>%)来将字符列mycolumn转换为因子。这是另一种简短的方法。

library(magrittr)

mydf$mycolumn %<>% factor

请添加更多信息。我们不鼓励仅包含代码和“尝试此方法”的答案,因为它们没有可搜索的内容,并且没有解释为什么有人应该“尝试此方法”。我们在这里努力成为知识资源。 - Brian Tompsett - 汤莱恩
请问如果我想在数据框的所有列中使用它,应该怎么做? - Mostafa90

6

我使用一个函数来完成这个操作。在这种情况下,我只将字符变量转换为因子变量:

for (i in 1:ncol(data)){
    if(is.character(data[,i])){
        data[,i]=factor(data[,i])
    }
}

我相信你需要双括号来实际提取列并将其更改为因子,例如 [[i]] - RTrain3k

3
除非你需要自动识别列,否则我发现这是最简单的解决方案:
df$name <- as.factor(df$name)

这使得数据框 df 中的列 name 成为一个因子。


2
您可以使用新的 dplyr 1.0.0 来使用 across
library(dplyr)

df <- mtcars 
#To turn 1 column to factor
df <- df %>% mutate(cyl = factor(cyl))

#Turn columns to factor based on their type. 
df <- df %>% mutate(across(where(is.character), factor))

#Based on the position
df <- df %>% mutate(across(c(2, 4), factor))

#Change specific columns by their name
df <- df %>% mutate(across(c(cyl, am), factor))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接