R dplyr:使用字符串函数重命名变量

时间:2015-05-21 19:39:58

标签: regex r rename dplyr

(有些相关问题:Enter new column names as string in dplyr's rename function

this.controls.add(picBox); 链(dplyr)的中间,我想用旧名称的函数替换多个列名称(使用%>%tolower,等)

gsub

我看到library(tidyr); library(dplyr) data(iris) # This is what I want to do, but I'd like to use dplyr syntax names(iris) <- tolower( gsub("\\.", "_", names(iris) ) ) glimpse(iris, 60) # Observations: 150 # Variables: # $ sepal_length (dbl) 5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6,... # $ sepal_width (dbl) 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4,... # $ petal_length (dbl) 1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4,... # $ petal_width (dbl) 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3,... # $ species (fctr) setosa, setosa, setosa, setosa, s... # the rest of the chain: iris %>% gather(measurement, value, -species) %>% group_by(species,measurement) %>% summarise(avg_value = mean(value)) 将参数?rename视为replace

所以我试过了:

named character vector, with new names as values, and old names as names.

但是这个(a)返回iris %>% rename(replace=c(names(iris)=tolower( gsub("\\.", "_", names(iris) ) ) )) 和(b)需要通过名称引用链中前一个操作的数据框,在我的实际用例中我不能这样做。

Error: unexpected '=' in iris %>% ...

8 个答案:

答案 0 :(得分:39)

这是一个非常晚的答案,2017年5月

dplyr 0.5.0.9004开始,很快就会是0.6.0,许多重新命名列的新方法(符合maggritr管道运算符%>%)已添加到包中。

这些功能是:

  • rename_all
  • rename_if
  • rename_at

使用这些功能的方法有很多种,但使用stringr包时与您的问题相关的方法如下:

df <- df %>%
  rename_all(
      funs(
        stringr::str_to_lower(.) %>%
        stringr::str_replace_all(., '\\.', '_')
      )
  )

所以,继续使用管道:)(没有双关语)。

答案 1 :(得分:36)

我认为您正在查看plyr::rename的文档,而不是dplyr::rename。您可以使用dplyr::rename执行类似的操作:

iris %>% rename_(.dots=setNames(names(.), tolower(gsub("\\.", "_", names(.)))))

答案 2 :(得分:22)

这是一种解决有点尴尬rename语法的方法:

myris <- iris %>% setNames(tolower(gsub("\\.","_",names(.))))

答案 3 :(得分:9)

对于这个特殊[但相当常见]的情况,该函数已经写在janitor包中:

library(janitor)

iris %>% clean_names()

##   sepal_length sepal_width petal_length petal_width species
## 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
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa
## .          ...         ...          ...         ...     ...

所以一起,

iris %>% 
    clean_names() %>%
    gather(measurement, value, -species) %>%
    group_by(species,measurement) %>%
    summarise(avg_value = mean(value))

## Source: local data frame [12 x 3]
## Groups: species [?]
## 
##       species  measurement avg_value
##        <fctr>        <chr>     <dbl>
## 1      setosa petal_length     1.462
## 2      setosa  petal_width     0.246
## 3      setosa sepal_length     5.006
## 4      setosa  sepal_width     3.428
## 5  versicolor petal_length     4.260
## 6  versicolor  petal_width     1.326
## 7  versicolor sepal_length     5.936
## 8  versicolor  sepal_width     2.770
## 9   virginica petal_length     5.552
## 10  virginica  petal_width     2.026
## 11  virginica sepal_length     6.588
## 12  virginica  sepal_width     2.974

答案 4 :(得分:7)

我使用base,stringr和dplyr的雄辩尝试:

编辑:库(tidyverse)现在包括所有三个库。

library(tidyverse)
library(maggritr) # Though in tidyverse to use %>% pipe you need to call it 
# library(dplyr)
# library(stringr)
# library(maggritr)

names(iris) %<>% # pipes so that changes are apply the changes back
    tolower() %>%
    str_replace_all(".", "_")

我这样做是为了用管道来构建功能。

my_read_fun <- function(x) {
    df <- read.csv(x) %>%
    names(df) %<>%
        tolower() %>%
        str_replace_all("_", ".")
    tempdf %<>%
        select(a, b, c, g)
}

答案 5 :(得分:1)

select()select_all()都可用于重命名列。

如果您只想重命名特定列,可以使用select

iris %>% 
  select(sepal_length = Sepal.Length, sepal_width = Sepal.Width, everything()) %>% 
  head(2)

  sepal_length sepal_width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa

rename做同样的事情,无需包含everything()

iris %>% 
  rename(sepal_length = Sepal.Length, sepal_width = Sepal.Width) %>% 
  head(2)

  sepal_length sepal_width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa

select_all()适用于所有列,可以将函数作为参数:

iris %>% 
  select_all(tolower)

iris %>% 
  select_all(~gsub("\\.", "_", .)) 

或将两者结合起来:

iris %>% 
  select_all(~gsub("\\.", "_", tolower(.))) %>% 
  head(2)

  sepal_length sepal_width petal_length petal_width species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa

答案 6 :(得分:1)

如果您不想自己编写正则表达式,可以使用

  • 非常灵活的snakecase-pkg
  • janitor::make_clean_names()具有一些不错的默认值,或者
  • janitor::clean_names()make_clean_names()相同,但直接作用于数据帧。

在管道内部调用它们应该很简单。

library(magrittr)
library(snakecase)

iris %>% setNames(to_snake_case(names(.)))
iris %>% tibble::as_tibble(.name_repair = to_snake_case)
iris %>% purrr::set_names(to_snake_case)
iris %>% dplyr::rename_all(to_snake_case)
iris %>% janitor::clean_names()

答案 7 :(得分:1)

截至2020年,rename_ifrename_atrename_all被标记为已取代。解决此问题的最新方法是rename_with()

iris %>% rename_with(tolower)

或更复杂的版本:

iris %>% 
  rename_with(stringr::str_replace, 
              pattern = "Length", replacement = "len", 
              matches("Length"))