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

how to rename a variable using a dynamic name and dplyr?

提问人:Malta 提问时间:4/4/2018 最后编辑:Malta 更新时间:9/8/2021 访问量:17366

问:

我想重命名函数中的一列,并将名称作为此函数的参数传递。基本上,我有一个函数

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

我希望这个函数用“name”更改 Sepal.length 列名(name 取 name 的值) 我尝试了不同的东西,例如

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的理解还是很基础的,它甚至没有编译。

r dplyr nse

评论

0赞 Malta 4/6/2018
不知道我的问题出了什么问题,我试图发展我的例子,如果这不是问题,有人可以解释一下它有什么问题吗?谢谢

答:

7赞 Shique 4/4/2018 #1

可以改用基础 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
32赞 Roman 4/4/2018 #2

你可以试试

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 软件包 (v0.2.0) 于 2018-04-04 创建。

或者你可以使用{{...}}

produce_data_frame <- function(name) {
  iris %>%
    as_tibble() %>% 
    select({{name}} := Sepal.Length)
}
22赞 GGamba 4/4/2018 #3

使用 dplyr 小插图编程中的不同输入和输出变量中,我们可以使用运算符::=

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"

评论

1赞 Helene 9/26/2021
这很干净,很漂亮!
1赞 philiporlando 3/22/2022
我不知道 dplyr 有一个海象操作员。感谢分享!
6赞 xaviescacs 5/22/2021 #4

使用 并且几乎不需要编写这样的函数,因为您始终可以执行以下操作: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