Convert all columns to characters in a data.frame
Solution 1
EDIT: 2021-03-01
Beginning with dplyr 1.0.0, the _all()
function variants are superceded. The new way to accomplish this is using the new across()
function.
library(dplyr)
mtcars %>%
mutate(across(everything(), as.character))
With across()
, we choose the set of columns we want to modify using tidyselect helpers (here we use everything()
to choose all columns), and then specify the function we want to apply to each of the selected columns. In this case, that is as.character()
.
Original answer:
You can also use dplyr::mutate_all
.
library(dplyr)
mtcars %>%
mutate_all(as.character)
Solution 2
In base R:
x[] <- lapply(x, as.character)
This converts the columns to character class in place, retaining the data.frame's attributes. A call to data.frame()
would cause them to be lost.
Attribute preservation using dplyr: Attributes seem to be preserved during dplyr::mutate(across(everything(), as.character))
. Previously they were destroyed by dplyr::mutate_all
.
Example
x <- mtcars
attr(x, "example") <- "1"
In the second case below, the example
attribute is retained:
# Destroys attributes
data.frame(lapply(x, as.character)) %>%
attributes()
# Preserves attributes
x[] <- lapply(x, as.character)
attributes(x)
Solution 3
This might work, but not sure if it's the best.
df = data.frame(lapply(mtcars, as.character))
str(df)
Solution 4
Most efficient way using data.table
-
data.table::setDT(mtcars)
mtcars[, (colnames(mtcars)) := lapply(.SD, as.character), .SDcols = colnames(mtcars)]
Note: You can use this to convert few columns of a data table
to your desired column type.
If we want to convert all columns to character then we can also do something like this-
to_col_type <- function(col_names,type){
get(paste0("as.", type))(dt[[col_names]])
}
mtcars<- rbindlist(list(Map(to_col_type ,colnames(mtcars),"character")))
Solution 5
mutate_all
in the accepted answer is superseded.
You can use mutate()
function with across()
:
library(dplyr)
mtcars %>%
mutate(across(everything(), as.character))
Comments
-
userJT almost 2 years
Consider a data.frame with a mix of data types.
For a weird purpose, a user needs to convert all columns to characters. How is it best done? A tidyverse attempt at solution is this:
map(mtcars,as.character) %>% map_df(as.list) %>% View() c2<-map(mtcars,as.character) %>% map_df(as.list)
when I call
str(c2)
it should say a tibble or data.frame with all characters.The other option would be some parameter settings for
write.csv()
or inwrite_csv()
to achieve the same thing in the resulting file output. -
sindri_baldur almost 6 yearsI think this can be simplified to
x[] <- lapply(x, as.character)
-
stevec almost 5 yearsThis is the best answer IMO, on the basis that it preserves attributes of the data.frame. @Sam is there any reason not to simply as sindri suggests?
-
Sam Firke over 3 yearsgood call, I have updated the answer with this simpler command
-
vasili111 over 3 years@sindri_baldur Could you please clarify how
x[] <- lapply(x, as.character)
works? I mean,lapply
accepts list and returns list. How herelapply
is working with data frame? -
sindri_baldur over 3 years@vasili111 Adding
[]
forces it to not lose its attributes (data.frame
in this case (which is built on a special type of lists)). -
vasili111 over 3 years@sindri_baldur Thank you.
-
Henrik about 3 years@vasili111 See also Assignment to empty index (empty square brackets) on LHS
-
Jake Thompson about 3 yearsThanks! I've updated my answer to reflect the updated dplyr syntax.