如何使用动态名称和dplyr重命名变量?

时间:2018-04-04 11:57:08

标签: r dplyr nse

我想重命名一个函数内的列,其名称作为此函数的参数传递。基本上,我有一个功能

produce_data_frame <- function(name) {
  return(iris)
}

我希望这个函数用'name'更改Sepal.length列名(名称取名称) 我试过了不同的东西,比如

produce_data_frame <- function(name) {
  name <- enquo(name)
  iris %>%
    rename((!!name) = Sepal.Length) %>%
    return()
}

打电话时

produce_data_frame("newName")

我想使用名为newName的Sepal.Length列返回iris data.frame。但我对NSE的理解仍然非常基础,甚至无法编译。

4 个答案:

答案 0 :(得分:9)

你可以尝试

library(tidyverse)

produce_data_frame <- function(name) {
  iris %>%
    as.tibble() %>% 
    select(!!quo_name(name) := Sepal.Length)
}

produce_data_frame("new_name")
#> # A tibble: 150 x 1
#>    new_name
#>       <dbl>
#>  1     5.10
#>  2     4.90
#>  3     4.70
#>  4     4.60
#>  5     5.00
#>  6     5.40
#>  7     4.60
#>  8     5.00
#>  9     4.40
#> 10     4.90
#> # ... with 140 more rows

reprex package(v0.2.0)创建于2018-04-04。

答案 1 :(得分:4)

您可以改为使用基础R names()

produce_data_frame <- function(name) {
  temp_df <- iris
  names(temp_df)[names(temp_df) == "Sepal.Length"] <- name
  return(temp_df)
}

produce_data_frame("newName")
#        newName 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

答案 2 :(得分:4)

使用dplyr编程插图中的Different input and output variable,我们可以使用:=运算符:

library(dplyr)
library(rlang)


produce_data_frame <- function(name) {
  name = quo_name(name)
  iris %>%
    rename(!!name := Sepal.Length)
}

produce_data_frame('test') %>% colnames()
#> [1] "test"         "Sepal.Width"  "Petal.Length" "Petal.Width" 
#> [5] "Species"

答案 3 :(得分:1)

使用 dplyr::renameglue 几乎不需要编写这样的函数,因为您始终可以执行以下操作:

library(glue)
library(dplyr)
name <- "new_name"
rename(iris,"{name}" := Sepal.Length)

如果需要一个功能,有很多方法可以实现。以下是重命名命名向量或列表(包括数据框)的通用函数:

rename_named_obj <- function(named_obj,new_names) {
  setNames(named_obj,
    purrr::map2_chr(names(named_obj),
                    names(new_names)[match(names(named_obj),new_names)],
      ~ {
        ifelse(is.na(.y),.x,.y)
      })
  )
}

给出以下结果:

> new_iris_names <- list("new_name1"="Sepal.Length","new_name2"="Petal.Length")
> rename_named_obj(iris,new_iris_names) %>% colnames()
[1] "new_name1"   "Sepal.Width" "new_name2"   "Petal.Width" "Species"    
> rename_named_obj(setNames(1:5,colnames(df)),new_iris_names)
  new_name1 Sepal.Width   new_name2 Petal.Width     Species 
          1           2           3           4           5