Подтвердить что ты не робот

Dplyr меняет многие типы данных

чтобы изменить типы данных, я могу использовать что-то вроде

l1 <- c("fac1","fac2","fac3")
l2 <- c("dbl1","dbl2","dbl3")
dat[,l1] <- lapply(dat[,l1], factor)
dat[,l2] <- lapply(dat[,l2], as.numeric)

с dplyr

dat <- dat %>% mutate(
    fac1 = factor(fac1), fac2 = factor(fac2), fac3 = factor(fac3),
    dbl1 = as.numeric(dbl1), dbl2 = as.numeric(dbl2), dbl3 = as.numeric(dbl3)
)

есть ли более элегантный (более короткий) путь в dplyr?

ТНХ Christof

4b9b3361

Ответ 1

Вы можете использовать стандартную оценочную версию mutate_each (которая является mutate_each_) для изменения классов столбцов:

dat %>% mutate_each_(funs(factor), l1) %>% mutate_each_(funs(as.numeric), l2)

Ответ 2

В нижней части ?mutate_each (по крайней мере, в dplyr 0.5), похоже, что эта функция, как и в ответе discdus @docendo, будет устаревать и заменяться более гибкими альтернативами mutate_if, mutate_all и mutate_at. Наиболее похожее на то, что @hadley упоминает в своем комментарии, вероятно, использует mutate_at. Обратите внимание, что порядок аргументов меняется на противоположный, по сравнению с mutate_each, а vars() использует select() как семантику, которую я интерпретирую как функцию ?select_helpers.

dat %>% mutate_at(vars(starts_with("fac")),funs(factor)) %>%   
  mutate_at(vars(starts_with("dbl")),funs(as.numeric))

Но mutate_at может принимать номера столбцов вместо аргумента vars(), и после прочтения этой страницы и рассмотрения альтернатив я закончил использование mutate_at, но с grep, чтобы захватить множество разных типов имена столбцов сразу (если у вас всегда есть такие очевидные имена столбцов!)

dat %>% mutate_at(grep("^(fac|fctr|fckr)",colnames(.)),funs(factor)) %>%
  mutate_at(grep("^(dbl|num|qty)",colnames(.)),funs(as.numeric))

Мне очень понравилось выяснять mutate_at + grep, потому что теперь одна строка может работать на множестве столбцов.

EDIT - теперь я вижу matches() среди select_helpers, который обрабатывает регулярное выражение, поэтому теперь мне это нравится.

dat %>% mutate_at(vars(matches("fac|fctr|fckr")),funs(factor)) %>%
  mutate_at(vars(matches("dbl|num|qty")),funs(as.numeric))

Другой общий комментарий - если у вас есть все столбцы дат с подходящими именами и согласованные форматы, это очень удобно. В моем случае это превратит все мои столбцы YYYYMMDD, которые были прочитаны как числа, в даты.

  mutate_at(vars(matches("_DT$")),funs(as.Date(as.character(.),format="%Y%m%d")))

Ответ 3

Поскольку ответ Ника к настоящему моменту устарел, а комментарий Рафаэля действительно полезен, я хочу добавить его в качестве ответа. Если вы хотите изменить все столбцы factor на character используйте mutate_if:

dat %>% mutate_if(is.factor, as.character)

Также разрешены другие функции. Например, я использовал iconv чтобы изменить кодировку всех столбцов character:

dat %>% mutate_if(is.character, function(x){iconv(x, to = "ASCII//TRANSLIT")})

или заменить все NA на 0 в числовых столбцах:

dat %>% mutate_if(is.numeric, function(x){ifelse(is.na(x), 0, x)})

Ответ 4

Более общий способ достижения преобразования типа столбцов выглядит следующим образом:

Если вы хотите преобразовать все столбцы фактор в столбцы символ, например, это можно сделать, используя один канал:

df %>%  mutate_each_( funs(as.character(.)), names( .[,sapply(., is.factor)] ))

Ответ 5

Это однострочник с mutate_at:

dat %>% mutate_at("l1", factor) %>% mutate_at("l2", as.numeric)

Ответ 6

Или, может быть, еще проще с convert из hablar:

library(hablar)

dat %>% 
  convert(fct(fac1, fac2, fac3),
          num(dbl1, dbl2, dbl3))

или сочетается с tidyselect:

dat %>% 
  convert(fct(contains("fac")),
          num(contains("dbl")))