将 data.frame 列格式从字符转换为因子

Convert data.frame column format from character to factor

提问人:Rasoul 提问时间:2/13/2012 最后编辑:zx8754Rasoul 更新时间:1/15/2022 访问量:499387

问:

我想将我的 data.frame 对象 () 的某些列的格式(类)从字符更改为因子mydf

当我按功能读取文本文件时,我不想这样做。read.table()

任何帮助将不胜感激。

数据帧 字符 R-FAQ

评论

19赞 tim riffe 2/13/2012
mydf$myfavoritecolumn <- as.factor(mydf$myfavoritecolumn)
0赞 Rasoul 2/13/2012
谢谢!但我还有另一个问题。我在字符数组 col_names[] 中拥有每列的名称。如何使用上述命令 (mydf$col_names[i]) 不起作用。
0赞 Etienne Low-Décarie 10/25/2012
有什么方法可以自动为所有字符变量执行此操作,就像 data.frame 使用 stringsAsFactors 一样?
0赞 IRTFM 8/18/2013
@EtienneLow-Décarie:公正,并在结果上使用。unclassdata.frame

答:

241赞 Tyler Rinker 2/13/2012 #1

嗨,欢迎来到 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

评论

0赞 Rasoul 2/13/2012
谢谢!但我还有另一个问题。我在字符数组 col_names[] 中拥有每列的名称。如何使用上述命令(既不起作用,也不起作用。mydf$col_names[i]mydf[,col_names[i]]
1赞 DrDom 2/13/2012
@Rasoul,会这样做mydf[, col_names]
4赞 Roman Luštrik 2/13/2012
+1 为裁判。这是基本的东西,可以问,但了解这些(和类似)工作所投入的大量工作也很好。
102赞 IRTFM 2/13/2012 #2
# 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)

解释。所有数据帧都是列表,与多个值参数一起使用的结果同样是列表,因此遍历列表是 的任务。上面的赋值将创建一组列表,函数应成功将其粘贴回数据帧中,[lapplydata.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赞 WGray 8/9/2014
这是一个非常好的解决方案!它还可以处理列号,如果您想更改许多但不是全部,这可能特别有用。例如,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)。
0赞 P Schnell 9/12/2016
注意:如果出现以下情况,则第一种解决方案不起作用。在这种情况下,会自动降级为向量而不是长度为 1 的列表,然后尝试对每个条目而不是整个列进行操作。这可以通过使用 .length(col_names)==1df[,col_names]lapplydf[,col_names,drop=FALSE]
0赞 IRTFM 9/12/2016
这是一个很好的观点。另一个保留列表状态的调用是使用 .df[col_names]
18赞 Sam Firke 1/8/2016 #3

如果要在加载数据后将 data.frame 中的所有字符变量更改为因子,可以像这样将其更改为名为 :dat

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

这将创建一个向量,用于标识哪些列属于 类,然后应用于这些列。characteras.factor

示例数据:

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

评论

0赞 Sam Firke 1/8/2016
每个字符变量到因子的完全转换通常发生在读取数据时,例如,使用 ,但当您从包中读取数据并想要训练一个不接受字符变量的随机森林模型时,这很有用。stringsAsFactors = TRUEread_excel()readxl
14赞 chriad 6/24/2016 #4

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

library(magrittr)

mydf$mycolumn %<>% factor

评论

0赞 Brian Tompsett - 汤莱恩 6/24/2016
请编辑更多信息。不鼓励使用纯代码和“试试这个”答案,因为它们不包含可搜索的内容,并且不解释为什么有人应该“试试这个”。我们在这里努力成为知识的资源。
0赞 Mostafa90 1/26/2017
请问,如果我不想将它用于我的 df 的所有列?
6赞 Edu Marín 6/2/2017 #5

我用一个函数来做。在本例中,我只将字符变量转换为因式分解:

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

评论

0赞 RTrain3k 11/14/2019
我相信您需要双括号才能实际提取列并将其更改为因子,例如[[i]]
36赞 sbha 4/10/2018 #6

您可以使用将所有字符列或选择命名字符列转换为因子: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)

评论

0赞 emr2 9/28/2022
mutate_at当你有很多列(~50000)并且你只需要转换 3 时,它真的很快。
3赞 Christian Lindig 12/26/2020 #7

除非您需要自动识别列,否则我发现这是最简单的解决方案:

df$name <- as.factor(df$name)

这使得 DataFrame 中的列成为一个因素。namedf

2赞 Ronak Shah 7/14/2021 #8

您可以使用新的 1.0.0acrossdplyr

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))