简体   繁体   中英

convert all factor columns to character in a data.frame without affecting non-factor columns

For example I have a data.frame with both integer column and factor columns.

data <- data.frame(
    a = 1:5, 
    b = factor(c("a", "b", "c", "d", "e")), 
    c = factor(c("f", "g", "h", "i", "j")))`

And I want to convert b and c factor columns into character, with keeping column a as integer.

I tried the follwing code :

sapply(data, function(x) {if_else(is.factor(x), as.character(x), x)})

Instead of getting the result, it throws an error:

Error: true must be length 1 (length of condition ), not 5

I knew this can be done by mutate_if function in dplyr. But I still wonder why my code does not work for this case.

Thank you very much for any suggestions!

You can try:

library(tidyverse)
d <- data.frame(a = 1:5, 
                b = factor(c("a", "b", "c", "d", "e")), 
                c = factor(c("f", "g", "h", "i", "j")))
d %>% glimpse() 
Observations: 5
Variables: 3
$ a <int> 1, 2, 3, 4, 5
$ b <fctr> a, b, c, d, e
$ c <fctr> f, g, h, i, j

d %>% 
  mutate_if(is.factor, as.character) %>% 
  glimpse()
Observations: 5
Variables: 3
$ a <int> 1, 2, 3, 4, 5
$ b <chr> "a", "b", "c", "d", "e"
$ c <chr> "f", "g", "h", "i", "j"

Using base R you can try

d[] <- lapply(d, function(x) if(is.factor(x)) as.character(x) else x)

For those who would like to use base R and preserve the data frame structure, rather than the list from lapply :

factor_to_characters = function(x)
{
    factor_cols = sapply(x, is.factor)
    x[factor_cols] = lapply(x[factor_cols], as.character)
    x   
}

Test it out:

> class(iris[, "Species"])
[1] "factor"
> 
> i2 = factor_to_character(iris)
> class(i2[, "Species"])
[1] "character"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM