R中三点省略号的更新值
我有一个函数R中三点省略号的更新值,r,parameter-passing,ellipsis,rlang,R,Parameter Passing,Ellipsis,Rlang,我有一个函数foo() 我认为在这里使用某种通用的包装器(runtime\u gateway())并通过..向foo()传递参数是有意义的,因此我可以利用相同的“runtime gateway logic”处理具有不同参数集的任意函数 如果在while循环中运行foo(),我想更新它的一些参数,同时保留其他参数的默认值或传递值 我该怎么做 我了解rlang::dot_list(…)和朋友,并快速浏览了一下。看起来,其中任何一个都只允许从省略号内容中提取值或检查省略号内容,但我不知道如何“在传输过
foo()
我认为在这里使用某种通用的包装器(runtime\u gateway()
)并通过..
向foo()
传递参数是有意义的,因此我可以利用相同的“runtime gateway logic”处理具有不同参数集的任意函数
如果在while循环中运行foo()
,我想更新它的一些参数,同时保留其他参数的默认值或传递值
我该怎么做
我了解rlang::dot_list(…)
和朋友,并快速浏览了一下。看起来,其中任何一个都只允许从省略号内容中提取值或检查省略号内容,但我不知道如何“在传输过程中更新它”
雷普雷克斯
foo id_b:2020-02-21 14:10:22.906
#>身份证号码:2020-02-21 14:10:23.908
运行时网关(run_mode=“while”,at=lubridate::ymd_hms(“2020-02-21 10:30:00”))
#>“at”通过省略号传递:
#> 2020-02-21 10:30:00
#>fun中的错误(at=at+60,…):形式参数“at”与多个实际参数匹配
由(v0.3.0)于2020-02-21创建,您可以通过添加
at
参数(如果不存在)来确保dots
包含at
参数,然后使用dots
而不是。
调用
runtime\u gateway在最后一行中,你为什么要尝试传递一个at
参数,而它已经默认为Sys.time()
?我的意思是,你通过传递at=Sys.time()
给它一个固定的时间。为什么不将while循环中的fun(at=Sys.time(),…)
更改为fun(…)
,并且根本不传递at
参数?@AllanCameronat
和Sys.time()
只是一些参数的示例,如果函数在中运行而loop@AllanCameron:我已经更新了我的问题,希望在中更新的部分,而clear稍微更为惯用:rlang::exec(fun,!!!dots)
而不是do.call(…)
。另外,rlang::list2()
比rlang::dots\u list()
有一个更简单的API。很抱歉,我花了几天时间才回到这个问题上。感谢您的回答,并感谢@krlmlr将其放在rlang
rails上。然而,通过切换到do.call()
或rlang::exec()
我基本上失去了传递的“易用性”…
甚至更远的下游,对吗?在保留语法糖分的同时,..
本质上是一个“语法糖化的美化arg列表”,难道没有办法改变它吗?@Rappster:使用do.call()调用的函数的签名中仍然有省略号。我不知道有一种文档化的方法可以更新部分…
。
foo <- function(
id = "id_a",
at = Sys.time()
) {
message(stringr::str_glue("{id}: {at}"))
Sys.sleep(1)
}
runtime_gateway <- function(
fun = foo,
run_mode = c("once", "while"),
... # Args to be passed to `fun`
) {
run_mode <- match.arg(run_mode)
if (run_mode == "once") {
fun(...)
} else if (run_mode == "while") {
counter <- 0
while(counter < 3) {
# Goal: keep ellipsis value for `id` but *update* value for `at`
dots <- rlang::dots_list(...)
at <- if ("at" %in% names(dots)) {
message("`at` was passed via ellipsis:")
message(dots$at)
dots$at
} else {
Sys.time()
}
fun(at = at + 60, ...)
counter <- counter + 1
}
}
}
runtime_gateway()
#> id_a: 2020-02-21 14:09:16.779
runtime_gateway(at = lubridate::ymd_hms("2020-02-21 10:30:00"))
#> id_a: 2020-02-21 10:30:00
runtime_gateway(run_mode = "while")
#> id_a: 2020-02-21 14:10:18.897
#> id_a: 2020-02-21 14:10:19.900
#> id_a: 2020-02-21 14:10:20.902
runtime_gateway(run_mode = "while", id = "id_b")
#> id_b: 2020-02-21 14:10:21.905
#> id_b: 2020-02-21 14:10:22.906
#> id_b: 2020-02-21 14:10:23.908
runtime_gateway(run_mode = "while", at = lubridate::ymd_hms("2020-02-21 10:30:00"))
#> `at` was passed via ellipsis:
#> 2020-02-21 10:30:00
#> Error in fun(at = at + 60, ...): formal argument "at" matched by multiple actual arguments
runtime_gateway()
#> id_a: 2020-02-21 14:22:07
runtime_gateway(at = lubridate::ymd_hms("2020-02-21 10:30:00"))
#> id_a: 2020-02-21 10:30:00
runtime_gateway(run_mode = "while")
#> id_a: 2020-02-21 14:23:09
#> id_a: 2020-02-21 14:23:10
#> id_a: 2020-02-21 14:23:11
runtime_gateway(run_mode = "while", id = "id_b")
#> id_b: 2020-02-21 14:23:12
#> id_b: 2020-02-21 14:23:13
#> id_b: 2020-02-21 14:23:14
runtime_gateway(run_mode = "while", at = lubridate::ymd_hms("2020-02-21 10:30:00"))
#> `at` was passed via ellipsis:
#> 2020-02-21 10:30:00
#> id_a: 2020-02-21 10:31:00
#> `at` was passed via ellipsis:
#> 2020-02-21 10:30:00
#> id_a: 2020-02-21 10:31:00
#> `at` was passed via ellipsis:
#> 2020-02-21 10:30:00
#> id_a: 2020-02-21 10:31:00