Как преобразовать все столбцы, где записи имеют длину ≤1, в числовые? - PullRequest
1 голос
/ 04 июля 2019

У меня есть фрейм данных с ~ 80 столбцами, и ~ 20-40 из этих столбцов имеют однозначные целые числа, которые хранятся в виде символов. Другие символьные столбцы являются полными предложениями (например, length >>> 1), поэтому при попытке ввести mutate_if(is.character, as.numeric).

его приводят к NA.

Я хотел бы эффективно их преобразовать, и на основании этого вопроса я надеялся на что-то вроде этого:

df %>% map_if(is.character & length(.) <= 1, as.numeric)

Однако это не работает. Я надеюсь на решение tidy, возможно, с использованием purrr?

Ответы [ 2 ]

3 голосов
/ 04 июля 2019

Лучшая функция для этих ситуаций - type_convert () , из readr:

"[type_convert() повторно конвертирует символьные столбцы во фрейме данных], что полезно, если вам нужно выполнить ручное манипулирование - вы можете прочитать столбцы как символьные, очистить их с помощью (например) регулярных выражений и другие преобразования, а затем пусть readr предпримет еще один удар при разборе. "

Итак, все, что вам нужно сделать, это добавить его в конец вашей трубы:

df %>% ... %>% type_convert() 

В качестве альтернативы мы можем использовать type.convert из base R, что автоматически определит тип столбца на основе значения и изменит его

df[] <- type.convert(df, as.is = TRUE)

Если ограничение заключается в поиске столбцов, содержащих только один символ

i1 <- !colSums(nchar(as.matrix(df)) > 1)
df[i1] <- type.convert(df[i1])

Если мы хотим использовать tidyverse, существует parse_guess с readr

library(tidyverse)
library(readr)
df %>%
     mutate_if(all(nchar(.) == 1), parse_guess)
1 голос
/ 04 июля 2019

Вы можете проверить nchar столбца в mutate_if

library(dplyr)
df %>%  mutate_if(~all(nchar(.) == 1) & is.character(.), as.numeric) 

Использование с примером данных

df <- data.frame(a = c("ab", "bc", "de", "de", "ef"), 
                 b = as.character(1:5), stringsAsFactors = FALSE)

df1 <- df %>% mutate_if(~all(nchar(.) == 1) & is.character(.), as.numeric) 

str(df1)
#'data.frame':  5 obs. of  2 variables:
# $ a: chr  "ab" "bc" "de" "de" ...
# $ b: num  1 2 3 4 5

Вы можете сделать то же самое с map_if, однако, он возвращает список обратно, и вам нужно преобразовать его обратно в фрейм данных

library(purrr)

df %>% 
   map_if(~all(nchar(.) == 1) & is.character(.), as.numeric) %>% 
   as.data.frame(., stringsAsFactors = FALSE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...