在这个例子中,我使用的是 iris
数据集,我想将 Petal.Length
重命名为 iris
:
library(dplyr)
some_fun <- function(x){
head(x) %>%
rename(!!quo_name(x) := "Petal.Length")
}
some_fun(iris)
但这会产生以下错误:
Error: `expr` must quote a symbol, scalar, or call
如果我使用 enquo
而不是 quo_name
,则会出现此错误:
Error: The LHS of `:=` must be a string or a symbol
我想问题出在我调用 some_fun(iris)
而不是 some_fun("iris")
,但我必须调用 some_fun (虹膜)
。
在使用 some_fun(iris)
时我该怎么做?
编辑:我需要这个函数来使用 purrr::map()
遍历列表。更新示例:
library(dplyr)
library(purrr)
list_df <- list(mtcars2 = mtcars %>% mutate(Petal.Length = 1),
iris2 = iris)
some_fun <- function(x){
df_name <- deparse(substitute(x))
head(x) %>%
rename("{df_name}" := "Petal.Length")
}
test <- map(list_df, some_fun)
list2env(test, .GlobalEnv)
mtcars2
iris2
最佳答案
尝试使用 deparse(substitute()) 获取数据集的名称,然后使用 dplyr 的新大括号进行非标准评估:
library(dplyr)
some_fun <- function(x){
df_name <- deparse(substitute(x)) #Comes out as string of df's name
head(x) %>%
rename("{df_name}" := "Petal.Length") #df_name is evaluated, THEN becomes the new variable name for Petal.Length
}
some_fun(iris)
基本上大括号内的所有内容都会首先求值。
编辑:这是基于 OP 更新的更新。只需预先提取名称,然后将它们传递给(稍微更新的)函数。
library(dplyr)
library(purrr)
list_df <- list(mtcars2 = mtcars %>% mutate(Petal.Length = 1),
iris2 = iris)
df_names <- names(list_df)
some_fun <- function(x, x_name){
df_name <- x_name
head(x) %>%
rename("{df_name}" := "Petal.Length")
}
test <- map2(list_df, df_names, some_fun)
list2env(test, .GlobalEnv)
mtcars2
# mpg cyl disp hp drat wt qsec vs am gear carb mtcars2
#1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 1
#2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 1
#3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 1
#4 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 1
#5 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2 1
#6 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1 1
iris2
# Sepal.Length Sepal.Width iris2 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
关于使用带有 dplyr 的数据框名称动态重命名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62679532/