如果按如下方式定义列表:list(param = "value1")
,则结果为:
> list(param = "value1")
#$param
#[1] "value1"
我尝试定义一个新的运算符%!=%
,以便我可以按如下方式定义一个列表:list(param %!=% "value1")
我希望结果为:
> list(param %!=% "value1")
#$param.ne
#[1] "value1"
作为背景,我正在为从数据库中提取数据的RESTful API编写R包装器。当您发出请求时,您可以告诉API返回与参数值param1 = value1
匹配的结果 - 这将直接包含在GET请求的查询字符串中。
但是,API还允许您提取与参数值不匹配的结果:param != value1
。将!=
放入请求的查询字符串会出现问题。该API旨在使用param.ne = value1
代替param != value1
。
目前,我尝试使用非标准评估中的一些元素来实现这一目标:
`%!=%` = function(query, value) {
query = deparse(substitute(query))
query = paste0("`", query, ".ne", "`", "=", "\"", value, "\"")
parse(text = query)
}
此函数将使用非标准评估确定查询类型(param
,param2
,param3
等),将查询转换为字符串,添加{{ 1}}到最后并将其作为表达式发回。
但是,如果我尝试.ne
,那么结果将是:
list(eval(param1 %!=% "value1"))
有没有一种简单的方法来实现上述目标?
编辑:
根据以下帖子,还有一个问题:
反正是否适应上述使用具有默认参数的函数?例如:
> list(eval(address %!=% "value1"))
#[[1]]
#[1] "value1"
我想做类似
的事情newlist <- function(param1 = "default1", param2 = "default2", ...)
结果是包含newlist(param2 = "non-default", param3 %!=% "stuff")
,param1 = "default1"
和param2 = "non-default"
的列表?
答案 0 :(得分:2)
您最好在list()
级别调用时解决此问题,而不是试图干扰参数名称替换。例如,考虑这个函数
newlist <- function(...) {
dots <- substitute(...())
op <- sapply(sapply(dots, '[[', 1), deparse)
car <- sapply(sapply(dots, '[[', 2), deparse)
cdr <- sapply(sapply(dots, "[[", 3), eval.parent)
stopifnot(all(op %in% c("==","!=")))
setNames(as.list(cdr), ifelse(op=="!=", paste0(car, ".ne"), car))
}
newlist(a == "b", c != "d")
# $a
# [1] "b"
# $c.ne
# [1] "d"
这里我们看一下你传递给函数的表达式,并确保它们是==
或!=
,并且可以构建适当的列表。
但如果你真的想使用你的功能,你可以做到
`%!=%` = function(query, value) {
field = paste0(deparse(substitute(query)), ".ne")
setNames(list(value), field)
}
a %!=% 5
# $a.ne
# [1] 5
请注意,这将直接返回一个列表。您可以将它们与c
c(a %!=% 5, b %!=% "fred")