Преобразуйте все столбцы в символы в data.frame

Рассмотрим data.frame со смесью типов данных.

Для странной цели пользователю нужно преобразовать все столбцы в символы. Как это лучше сделать? Попытка решения tidyverse такова:

map(mtcars,as.character) %>% map_df(as.list) %>% View()
c2<-map(mtcars,as.character) %>% map_df(as.list)

когда я вызываю str(c2), он должен сказать tibble или data.frame со всеми символами.

Другой вариант - это настройки некоторых параметров для write.csv() или write_csv(), чтобы добиться того же результата в результирующем выводе файла.


person userJT    schedule 04.05.2017    source источник


Ответы (5)


РЕДАКТИРОВАТЬ: 2021-03-01

Начиная с dplyr 1.0.0, варианты функции _all() заменяются. Новый способ добиться этого - использовать новую функцию across().

library(dplyr)
mtcars %>%
  mutate(across(everything(), as.character))

С помощью across() мы выбираем набор столбцов, которые хотим изменить, используя помощники tidyselect ( здесь мы используем everything() для выбора всех столбцов), а затем указываем функцию, которую мы хотим применить к каждому из выбранных столбцов. В данном случае это as.character().

Исходный ответ:

Вы также можете использовать dplyr::mutate_all.

library(dplyr)
mtcars %>%
  mutate_all(as.character)
person Jake Thompson    schedule 05.05.2017

В базе R:

x[] <- lapply(x, as.character)

Это преобразует столбцы в символьный класс на месте, сохраняя атрибуты data.frame. Вызов data.frame() приведет к их потере.

Сохранение атрибутов с помощью dplyr: похоже, что атрибуты сохраняются во время dplyr::mutate(across(everything(), as.character)). Ранее они были уничтожены dplyr::mutate_all.

Пример

x <- mtcars
attr(x, "example") <- "1"

Во втором случае ниже атрибут example сохраняется:

# Destroys attributes

data.frame(lapply(x, as.character)) %>%
  attributes()

# Preserves attributes

x[] <- lapply(x, as.character)
attributes(x)
person Sam Firke    schedule 26.01.2018
comment
Я думаю, это можно упростить до x[] <- lapply(x, as.character) - person sindri_baldur; 03.07.2018
comment
Это лучший ответ IMO, поскольку он сохраняет атрибуты data.frame. @Sam, есть ли причина не просто так, как предлагает Синдри? - person stevec; 16.07.2019
comment
хороший звонок, я обновил ответ с помощью этой более простой команды - person Sam Firke; 28.08.2020
comment
@sindri_baldur Не могли бы вы прояснить, как работает x[] <- lapply(x, as.character)? Я имею в виду, lapply принимает список и возвращает список. Как здесь lapply работает с фреймом данных? - person vasili111; 15.01.2021
comment
@ vasili111 Добавление [] заставляет его не терять свои атрибуты (в данном случае data.frame (который построен на специальном типе списков)). - person sindri_baldur; 15.01.2021
comment
@sindri_baldur Спасибо. - person vasili111; 15.01.2021

Это может сработать, но не уверен, что лучше.

df = data.frame(lapply(mtcars, as.character))
str(df)
person Sean Lin    schedule 04.05.2017

Самый эффективный способ использования data.table-

data.table::setDT(mtcars)
mtcars[, (colnames(mtcars)) := lapply(.SD, as.character), .SDcols = colnames(mtcars)]

Примечание. Это можно использовать для преобразования нескольких столбцов data table в столбец желаемого типа.

Если мы хотим преобразовать все столбцы в символы, мы также можем сделать что-то вроде этого:

to_col_type <- function(col_names,type){
            get(paste0("as.", type))(dt[[col_names]])
            }
mtcars<- rbindlist(list(Map(to_col_type ,colnames(mtcars),"character")))
person Rushabh Patel    schedule 26.01.2018

mutate_all в принятом ответе заменяется.

Функцию mutate() можно использовать с across():

library(dplyr)

mtcars %>% 
  mutate(across(everything(), as.character))
person HBat    schedule 22.02.2021
comment
Спасибо! Я обновил свой ответ, чтобы отразить обновленный синтаксис dplyr. - person Jake Thompson; 01.03.2021