我有一个数据帧。我们就叫他鲍勃吧:

> head(bob)
                 phenotype                         exclusion
GSM399350 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399351 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399352 3- 4- 8- 25- 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399353 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399354 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-
GSM399355 3- 4- 8- 25+ 44+ 11b- 11c- 19- NK1.1- Gr1- TER119-

我想连接这个数据帧的行(这将是另一个问题)。但看:

> class(bob$phenotype)
[1] "factor"

Bob的列是因子。举个例子:

> as.character(head(bob))
[1] "c(3, 3, 3, 6, 6, 6)"       "c(3, 3, 3, 3, 3, 3)"      
[3] "c(29, 29, 29, 30, 30, 30)"

我不太明白这一点,但我猜这些是进入鲍勃(卡拉克塔克斯国王的法庭)的列的因子水平的指数?不是我需要的。

奇怪的是,我可以徒手浏览bob的列

bob$phenotype <- as.character(bob$phenotype)

这很好。并且,在一些输入之后,我可以得到一个data.frame,它的列是字符而不是因子。我的问题是:我如何自动地做到这一点?我如何将一个data.frame与因子列转换为一个data.frame与字符列,而不必手动遍历每一列?

附加问题:为什么手动方法有效?


当前回答

如果你使用数据。表包对data.frame的操作,那么问题就不存在了。

library(data.table)
dt = data.table(col1 = c("a","b","c"), col2 = 1:3)
sapply(dt, class)
#       col1        col2 
#"character"   "integer" 

如果你在你的数据集中已经有一个因子列,你想把它们转换成字符,你可以这样做。

library(data.table)
dt = data.table(col1 = factor(c("a","b","c")), col2 = 1:3)
sapply(dt, class)
#     col1      col2 
# "factor" "integer" 
upd.cols = sapply(dt, is.factor)
dt[, names(dt)[upd.cols] := lapply(.SD, as.character), .SDcols = upd.cols]
sapply(dt, class)
#       col1        col2 
#"character"   "integer" 

其他回答

dplyr 1.0.0版引入了新函数“across”。新函数将取代作用域变量(_if, _at, _all)。这是官方文件

library(dplyr)
bob <- bob %>% 
       mutate(across(where(is.factor), as.character))

也许是一个更新的选择?

library("tidyverse")

bob <- bob %>% group_by_if(is.factor, as.character)

在数据帧的开头包含stringsAsFactors = FALSE以忽略所有误解。

更新:这里有一个不起作用的例子。我认为它会,但我认为stringsAsFactors选项只适用于字符串-它离开因子单独。

试试这个:

bob2 <- data.frame(bob, stringsAsFactors = FALSE)

一般来说,当你遇到应该是字符的因子的问题时,总会有一个stringsAsFactors设置来帮助你(包括一个全局设置)。

全局选项

stringsAsFactors: data.frame和read.table参数的默认设置。

可能是你想在你的启动文件(例如~/. rprofile)中设置为FALSE。请参阅帮助(选项)。