dplyr更改了许多数据类型

ckl*_*uss 52 r dataframe dplyr

更改数据类型我可以使用类似的东西

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

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)
)
Run Code Online (Sandbox Code Playgroud)

在dplyr中有更优雅(更短)的方式吗?

克里斯托夫

tal*_*lat 47

您可以使用mutate_each(即mutate_each_)的标准评估版本来更改列类:

dat %>% mutate_each_(funs(factor), l1) %>% mutate_each_(funs(as.numeric), l2)
Run Code Online (Sandbox Code Playgroud)

  • `mutate_each`在最新版本中已被弃用,请使用`mutate_at`代替...... (8认同)
  • 在这种情况下,您还可以使用`starts_with()` (7认同)
  • 谢谢你的建议,@ hadley.所以对于第一种情况是`dat%>%mutate_each(funs(factor),starts_with("fac"))`将所有以字符串"fac"开头的列转换为factor. (3认同)

Raf*_*yas 42

从的底部?mutate_each(至少在dplyr 0.5),它看起来像功能,如@docendo discimus的回答,将被弃用,并用更灵活的替代品取代mutate_if,mutate_allmutate_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))
Run Code Online (Sandbox Code Playgroud)

但是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))
Run Code Online (Sandbox Code Playgroud)

我非常兴奋找出mutate_at+ grep,因为现在一行可以处理很多列.

编辑 - 现在我matches()在select_helpers中看到,它处理正则表达式,所以现在我喜欢这个.

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

另一个与通常相关的注释 - 如果您的所有日期列都具有可匹配的名称和一致的格式,则这是强大的.就我而言,这会将我的所有YYYYMMDD列(都被读作数字)转换为日期.

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


lok*_*oki 28

由于尼克的回答现在已经被删除,而拉斐尔的评论非常有用,我想将其添加为答案.如果要更改要使用的所有 factor列:charactermutate_if

dat %>% mutate_if(is.factor, as.character)
Run Code Online (Sandbox Code Playgroud)

还允许其他功能.我例如用于iconv更改所有character列的编码:

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

  • `dat %&gt;% mutate_if(is.factor, as.character)` 将所有因子列更改为字符,是迄今为止最好的通用答案。 (2认同)

Eri*_*ntz 14

Dplyracross功能已取代_if_at_all。见vignette("colwise")

dat %>% 
mutate(across(all_of(l1), as.factor),
       across(all_of(l2), as.numeric))
Run Code Online (Sandbox Code Playgroud)


nex*_*tec 9

这是一个单线mutate_at

dat %>% mutate_at("l1", factor) %>% mutate_at("l2", as.numeric)
Run Code Online (Sandbox Code Playgroud)