使用管道操作符将dplyr的rename应用于所有列

21

我正在处理一个对应于下面摘录的导入数据集:

set.seed(1)
dta <- data.frame("This is Column One" = runif(n = 10),
                     "Another amazing Column name" = runif(n = 10),
                     "!## This Columns is so special€€€" = runif(n = 10),
                    check.names = FALSE)

我正在使用dplyr清理数据,并希望作为第二步更改列名为语法正确的名称并删除标点符号。 我尝试过的方法:

dta_cln <- dta %>% 
    rename(make.names(names(dta)))

生成一个错误:

> dta_clean <- dta %>% 
+     rename(make.names(names(dta)))
Error: All arguments to rename must be named.

期望的结果

我想要实现的可以在基础上完成:

names(dta) <- gsub("[[:punct:]]","",make.names(names(dta)))

它会返回:

which would return:
> names(dta)
[1] "ThisisColumnOne"          "AnotheramazingColumnname" "XThisColumnsissospecial"
我希望使用dyplr%>%来实现相同的效果。

看起来需要对这个进行一些调整。 - akrun
@akrun 非常感谢,我会尝试使用链接答案中建议的 setNames(tolower(gsub("\\.","_",names(.)))) 做一些事情。 - Konrad
唯一的问题是,一些字符在 rename 中无法正确解析。 - akrun
经过调整,这个可以工作了。 - Konrad
是的,独立软件应该可以在“rename”之外运行。但是,我明白使用“dplyr”函数本身使它正确的原因。 - akrun
显示剩余2条评论
5个回答

35

我知道这是一个老问题,而且我相信你现在已经找到了解决方案,但我搜索同样的问题时偶然来到这里,并最终找到了几种新的方法来解决它。

Dplyr

使用 dplyr 0.6.0 及以上版本,现在有一个 rename_all 函数:

  dta %>% 
    rename_all(funs(gsub("[[:punct:]]", "", make.names(names(dta)))))

这可以运行,但对我来说有点凌乱。如果您希望在dplyr中获得更多灵活性,还可以调用:

  • rename_at
  • rename_if

Janitor

这是一个相当不错的软件包(具有丰富的其他功能),可以轻松清理列名:

library(janitor)

dta %>% 
  clean_names()

这将重命名并清理所有列名为以下内容:

[1] "this_is_column_one"  "another_amazing_column_name"  "x_this_columns_is_so_special"

所有的命名方式都使用snake_case而不是CamelCase,但总体来说clean_names在处理列名方面非常灵活。如果这是一个不能接受的问题,您可以使用另一个包snakecase中的函数to_big_camel_case()rename_all函数中使用......尽管这有点太深奥了。


5
funs()在dplyr 0.8.0版本已被弃用。现在你应该使用dta %>% rename_all(list(~ gsub("[[:punct:]]", "", .)))或者(由于rename_all()已经被rename_with()替代...)dta %>% rename_with(~ gsub("[[:punct:]]", "", .x)) - Brian D

35

使用管道设置列名,例如:

iris %>% `colnames<-`(c("newcol1", "newcol2", "newcol3", "newcol4", "newcol5"))

返回哪个结果

    newcol1 newcol2 newcol3 newcol4    newcol5
1       5.1     3.5     1.4     0.2     setosa
2       4.9     3.0     1.4     0.2     setosa
3       4.7     3.2     1.3     0.2     setosa

6
mtcars %>% 
  data.table::setnames(
    old = mtcars %>% names(),
    new = mtcars %>% names() %>% paste0("_new_name")
  )
data.table包中的setnames函数用于重命名数据帧中的列名。我们需要使用oldnew这两个参数来调用此函数。 mtcars %>% names()使用管道符号%>% 输出数据框mtcars的列名,因此您还可以使用names(mtcars)。它们是同一件事。
在这个最简示例中,我使用管道符号%>% 重命名列名,并使用paste0函数添加所有旧列名的后缀。您可以添加前缀、后缀或其他规则。

请在您的回答中添加一些说明。例如,为什么您的答案比已接受的答案更好? - Jesse

3
你也可以尝试这个。
set.seed(1)
dta <- data.frame("This is Column One" = runif(n = 10),
                 "Another amazing Column name" = runif(n = 10),
                 "!## This Columns is so special€€€" = runif(n = 10),
                check.names = FALSE)

dta <- dta  %>% 
  setNames(gsub("[^[:alnum:] ]", perl = TRUE,
            "",
            names(.))) %>% 
  setNames(gsub("(\\w)(\\w*)",
            "\\U\\1\\L\\2",
            perl = TRUE,
            names(.)))

names(dta)
[1] "This Is Column One"          "Another Amazing Column Name" " This Columns Is So Special"

1
这应该是被接受的答案。其他的取决于首先分配数据框以便随后修改列名。谢谢! - Anurag N. Sharma

1

使用 StringrDplyr,以及 点运算符

dta %>%
   dplyr::rename_all(funs(
                     stringr::str_replace_all( ., "[[:punct:]]", "_" )
   ))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接