Some dataset contain factor-columns where you expected string-columns. Such problem commonly originate from the source of your data, when you imported or created the dataset. The best place to fix the problem is right there, usually by using the argument stringsAsFactors = FALSE to read.csv() or to data.frame(). But sometimes you have no choice other than fixing the problem after the fact. Here is how.

Let’s create an object which columns x and z are factors.

object <- data.frame(x = "A", y = 1, z = "Z", stringsAsFactors = TRUE)
object
##   x y z
## 1 A 1 Z

This is hard to see unless you inspect the object’s structure or convert the object to a tibble.

str(object)
## 'data.frame':    1 obs. of  3 variables:
##  $ x: Factor w/ 1 level "A": 1
##  $ y: num 1
##  $ z: Factor w/ 1 level "Z": 1
library(tibble)

as_tibble(object)
## # A tibble: 1 x 3
##   x         y z    
##   <fct> <dbl> <fct>
## 1 A         1 Z

Now it’s obvious that x and z are factors. How can we convert them to strings?

  • Option 1: Convert each column to a character, one by one.
object <- data.frame(x = "A", y = 1, z = "Z", stringsAsFactors = TRUE)
object$x <- as.character(object$x)
object$y <- as.character(object$z)

as_tibble(object)
## # A tibble: 1 x 3
##   x     y     z    
##   <chr> <chr> <fct>
## 1 A     Z     Z
  • Option 2: Use lapply() to do something similar to what I showed above, but in one single step.
object <- data.frame(x = "A", y = 1, z = "Z", stringsAsFactors = TRUE)
object[c("x", "y")] <- lapply(object[c("x", "y")], as.character)
as_tibble(object)
## # A tibble: 1 x 3
##   x     y     z    
##   <chr> <chr> <fct>
## 1 A     1     Z
    1. Use modify_if(): This is best not only because you avoid the weird assignment (object[]) but also because you don’t need to specify which are the factor-columns.
library(purrr)

object <- data.frame(x = "A", y = 1, z = "Z", stringsAsFactors = TRUE)
object <- modify_if(object, is.factor, as.character)
as_tibble(object)
## # A tibble: 1 x 3
##   x         y z    
##   <chr> <dbl> <chr>
## 1 A         1 Z