如何在 R 函数中 return a data-variable?
How do I return a data-variable in an R function?
我正在尝试做什么
我正在尝试编写一个函数,该函数 return 是数据集某些变量的名称。对于测试小标题test <- tibble(x1 = 1:3, x2=2:4, x3=3:5, x4=4:6)
,我想要一个函数
assign_predictors_argument <- function(dataset, outcome, predictors) {
...
}
这样:
- 如果未定义参数
predictors
,predictors
将被设置为dataset
中除outcome
之外的所有变量。例如。 assign_predictors_argument(test, x1)
将 return c(x2, x3, x4)
.
- 如果参数
predictors
已定义,将 return 该值。例如。 assign_predictors_argument(test, x1, c(x2, x3))
将 return c(x2, x3)
.
我试过的
assign_predictors_argument <- function(dataset, outcome, predictors) {
if(missing(predictors)) {
predictors <- dataset %>%
dplyr::select( -{{ outcome }} ) %>%
names()
}
predictors
}
哪里出了问题
案例 1:预测变量参数缺失
assign_predictors_argument(test, x1)
给出结果 "x2" "x3" "x4"
。但是,我希望这个 return c(x2,x3, x4)
.
如何将此字符向量转换为与输入类似的形式?
案例 2:预测参数定义
assign_predictors_argument(test, x1, c(x2, x3))
给出
Error in assign_predictors_argument(test, x1, x2) :
object 'x2' not found
函数的最后一行似乎试图求值 return predictors
。由于 x3 没有在环境中定义,这会带来错误。
我试过 a) 将最后一行更改为 {{predictors}}
以及 b) 将 missing(predictors)
更改为 is.null(predictors)
并输入默认值 predictors = NULL
(在 this).都没有用。
我怎样才能 return predictors
的值而不 a) 改变它的形式或 b) 评估它?
你说你想要 return 类似 c(x2, x3, x4)
的东西。我们先要明确这个对象是什么。它是函数 c
的未计算 call
。它不是名称向量。您将能够在整洁的评估中使用它,但它需要 !!
运算符。
这很难实现。您需要捕获 predictors
参数并确保它是单个变量名称或对 c
的调用。传递给 predictors
的任何其他表达式都可能会引发错误。
如果缺少 predictors
并且您将列名称作为字符获取,则必须将它们转换为具有 as.name
的名称并将它们粘贴到 c
调用中。如果 predictors
是单个变量,则必须 returned 未计算。如果是 c
调用,它也应该 return 未计算。否则会抛出错误。
所以函数可能看起来像这样:
assign_predictors_argument <- function(dataset, outcome, predictors) {
if(missing(predictors)) {
predictors <- dataset %>%
dplyr::select( -{{ outcome }} ) %>%
names() %>%
sapply(as.name, USE.NAMES = FALSE)
predictors <- as.call(c(quote(c), predictors))
} else {
predictors <- as.list(match.call())$predictors
if(is.call(predictors))
{
f_name <- as.list(predictors)[[1]]
if(as.character(substitute(f_name)) != "c")
stop("'predictors' must be either a single variable or vector of names")
}
}
predictors
}
那么让我们来测试一下:
test <- dplyr::tibble(x1 = 1:3, x2 = 2:4, x3 = 3:5, x4 = 4:6)
# Test with missing predictors
assign_predictors_argument(test, x1)
#> c(x2, x3, x4)
# Test with single predictor
assign_predictors_argument(test, x1, x2)
#> x2
# Test with multiple predictors
assign_predictors_argument(test, x1, c(x3, x4))
#> c(x3, x4)
# Test with call other than call to c
assign_predictors_argument(test, x1, as.name("x3"))
#> Error in assign_predictors_argument(test, x1, as.name("x3")):
#> 'predictors' must be either a single variable or vector of names
这一切看起来都是正确的。所以要使用它,我们可能会做这样的事情:
vars <- assign_predictors_argument(test, x1, c(x2, x4))
vars
#> c(x2, x4)
test %>% select(!!vars)
#> # A tibble: 3 x 2
#> x2 x4
#> <int> <int>
#> 1 2 4
#> 2 3 5
#> 3 4 6
由 reprex package (v0.3.0)
于 2020-07-10 创建
你很接近:
assign_predictors_argument <- function(dataset, outcome, predictors) {
if(missing(predictors)) {
dataset %>%
dplyr::select( -{{ outcome }} ) %>%
names() %>%
{rlang::expr( c(!!!syms(.)) )}
}
else rlang::enexpr(predictors)
}
assign_predictors_argument(test, x1)
# c(x2, x3, x4)
assign_predictors_argument(test, x1, c(x2, x3))
# c(x2, x3)
在上面,rlang::expr()
通过以下方式构造您想要的表达式:1) 使用 syms()
将名称转换为符号,以及 2) 在 c(...)
表达式中使用不引号将它们拼接在一起-拼接运算符!!!
.
对于第二部分,您可以简单地捕获用户使用 rlang::enexpr()
提供的表达式。
我正在尝试做什么
我正在尝试编写一个函数,该函数 return 是数据集某些变量的名称。对于测试小标题test <- tibble(x1 = 1:3, x2=2:4, x3=3:5, x4=4:6)
,我想要一个函数
assign_predictors_argument <- function(dataset, outcome, predictors) {
...
}
这样:
- 如果未定义参数
predictors
,predictors
将被设置为dataset
中除outcome
之外的所有变量。例如。assign_predictors_argument(test, x1)
将 returnc(x2, x3, x4)
. - 如果参数
predictors
已定义,将 return 该值。例如。assign_predictors_argument(test, x1, c(x2, x3))
将 returnc(x2, x3)
.
我试过的
assign_predictors_argument <- function(dataset, outcome, predictors) {
if(missing(predictors)) {
predictors <- dataset %>%
dplyr::select( -{{ outcome }} ) %>%
names()
}
predictors
}
哪里出了问题
案例 1:预测变量参数缺失
assign_predictors_argument(test, x1)
给出结果 "x2" "x3" "x4"
。但是,我希望这个 return c(x2,x3, x4)
.
如何将此字符向量转换为与输入类似的形式?
案例 2:预测参数定义
assign_predictors_argument(test, x1, c(x2, x3))
给出
Error in assign_predictors_argument(test, x1, x2) :
object 'x2' not found
函数的最后一行似乎试图求值 return predictors
。由于 x3 没有在环境中定义,这会带来错误。
我试过 a) 将最后一行更改为 {{predictors}}
以及 b) 将 missing(predictors)
更改为 is.null(predictors)
并输入默认值 predictors = NULL
(在 this).都没有用。
我怎样才能 return predictors
的值而不 a) 改变它的形式或 b) 评估它?
你说你想要 return 类似 c(x2, x3, x4)
的东西。我们先要明确这个对象是什么。它是函数 c
的未计算 call
。它不是名称向量。您将能够在整洁的评估中使用它,但它需要 !!
运算符。
这很难实现。您需要捕获 predictors
参数并确保它是单个变量名称或对 c
的调用。传递给 predictors
的任何其他表达式都可能会引发错误。
如果缺少 predictors
并且您将列名称作为字符获取,则必须将它们转换为具有 as.name
的名称并将它们粘贴到 c
调用中。如果 predictors
是单个变量,则必须 returned 未计算。如果是 c
调用,它也应该 return 未计算。否则会抛出错误。
所以函数可能看起来像这样:
assign_predictors_argument <- function(dataset, outcome, predictors) {
if(missing(predictors)) {
predictors <- dataset %>%
dplyr::select( -{{ outcome }} ) %>%
names() %>%
sapply(as.name, USE.NAMES = FALSE)
predictors <- as.call(c(quote(c), predictors))
} else {
predictors <- as.list(match.call())$predictors
if(is.call(predictors))
{
f_name <- as.list(predictors)[[1]]
if(as.character(substitute(f_name)) != "c")
stop("'predictors' must be either a single variable or vector of names")
}
}
predictors
}
那么让我们来测试一下:
test <- dplyr::tibble(x1 = 1:3, x2 = 2:4, x3 = 3:5, x4 = 4:6)
# Test with missing predictors
assign_predictors_argument(test, x1)
#> c(x2, x3, x4)
# Test with single predictor
assign_predictors_argument(test, x1, x2)
#> x2
# Test with multiple predictors
assign_predictors_argument(test, x1, c(x3, x4))
#> c(x3, x4)
# Test with call other than call to c
assign_predictors_argument(test, x1, as.name("x3"))
#> Error in assign_predictors_argument(test, x1, as.name("x3")):
#> 'predictors' must be either a single variable or vector of names
这一切看起来都是正确的。所以要使用它,我们可能会做这样的事情:
vars <- assign_predictors_argument(test, x1, c(x2, x4))
vars
#> c(x2, x4)
test %>% select(!!vars)
#> # A tibble: 3 x 2
#> x2 x4
#> <int> <int>
#> 1 2 4
#> 2 3 5
#> 3 4 6
由 reprex package (v0.3.0)
于 2020-07-10 创建你很接近:
assign_predictors_argument <- function(dataset, outcome, predictors) {
if(missing(predictors)) {
dataset %>%
dplyr::select( -{{ outcome }} ) %>%
names() %>%
{rlang::expr( c(!!!syms(.)) )}
}
else rlang::enexpr(predictors)
}
assign_predictors_argument(test, x1)
# c(x2, x3, x4)
assign_predictors_argument(test, x1, c(x2, x3))
# c(x2, x3)
在上面,rlang::expr()
通过以下方式构造您想要的表达式:1) 使用 syms()
将名称转换为符号,以及 2) 在 c(...)
表达式中使用不引号将它们拼接在一起-拼接运算符!!!
.
对于第二部分,您可以简单地捕获用户使用 rlang::enexpr()
提供的表达式。