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

> 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与字符列,而不必手动遍历每一列?

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


当前回答

也许是一个更新的选择?

library("tidyverse")

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

其他回答

或者你可以尝试transform:

newbob <- transform(bob, phenotype = as.character(phenotype))

只要确保把你想转换为字符的每一个因素。

或者你可以这样做,一击杀光所有害虫:

newbob_char <- as.data.frame(lapply(bob[sapply(bob, is.factor)], as.character), stringsAsFactors = FALSE)
newbob_rest <- bob[!(sapply(bob, is.factor))]
newbob <- cbind(newbob_char, newbob_rest)

像这样把数据塞进代码中并不是一个好主意,我可以单独做spapply部分(实际上,这样做要容易得多),但你明白了…我还没有检查代码,因为我不在家,所以我希望它能工作!=)

然而,这种方法有一个缺点……之后你必须重新组织列,而使用transform你可以做任何你想做的事情,但代价是“行人风格的代码编写”…

所以…=)

这对我来说很管用——我终于想出了一句话

df <- as.data.frame(lapply(df,function (y) if(class(y)=="factor" ) as.character(y) else y),stringsAsFactors=F)

另一种方法是使用apply转换它

bob2 <- apply(bob,2,as.character)

和一个更好的(前一个是'matrix'类)

bob2 <- as.data.frame(as.matrix(bob),stringsAsFactors=F)

这可以将所有内容转换为字符,然后将数字转换为数字:

makenumcols<-function(df){
  df<-as.data.frame(df)
  df[] <- lapply(df, as.character)
  cond <- apply(df, 2, function(x) {
    x <- x[!is.na(x)]
    all(suppressWarnings(!is.na(as.numeric(x))))
  })
  numeric_cols <- names(df)[cond]
  df[,numeric_cols] <- sapply(df[,numeric_cols], as.numeric)
  return(df)
}

改编自:自动获取excel表的列类型

如果你想要一个新的数据帧bobc,其中bobf中的每个因子向量都转换为字符向量,试试这个:

bobc <- rapply(bobf, as.character, classes="factor", how="replace")

如果希望将其转换回来,可以创建一个逻辑向量,其中的列是因子,并使用该逻辑向量选择性地应用因子

f <- sapply(bobf, class) == "factor"
bobc[,f] <- lapply(bobc[,f], factor)