将参数强制转换为最简单的类型
Coerce arguments to simplest type
当使用包 shiny 或 plumber 处理用户输入时,通常需要将字符参数转换为数字或逻辑参数。
我想自动完成,有什么有效的方法吗?
预期(这个或类似):
convert_args <- ...
fun <- function(a, b, c, d){
convert_args()
dplyr::lst(a, b, c , d)
}
fun("na","true","1","foo")
#> $a
#> [1] NA
#>
#> $b
#> [1] TRUE
#>
#> $c
#> [1] 1
#>
#> $d
#> [1] "foo"
一种选择是使用 readr::parse_guess
,顾名思义,它会尝试猜测字符向量的类型。
convert_args <- function(x) {
lapply(x, readr::parse_guess)
}
convert_args(c("NA","true","1","foo"))
#[[1]]
#[1] NA
#[[2]]
#[1] TRUE
#[[3]]
#[1] 1
#[[4]]
#[1] "foo"
当我们有 "na"
时,这不会直接起作用
readr::parse_guess("na")
#[1] "na"
但正如@Moody_Mudskipper 提到的,可以通过在 parse_guess
中指定 na
参数来解决
readr::parse_guess("na", c("na", "NA"))
#[1] NA
感谢@Ronak 的解决方案,我围绕 readr::parse_guess
构建了一个包装器以获得准确的预期输出。
我还添加了一个选项来评估未转换的字符输入,因为这也是一项常见任务。
convert_args <- function(na = c("", "NA"), locale = readr::default_locale(),
trim_ws = TRUE, guess_integer = FALSE, eval = FALSE){
if(!requireNamespace("readr"))
stop("convert_args() requires package readr to be installed")
args <- as.list(eval.parent(quote(match.call())))[-1]
args <- lapply(args, readr::parse_guess, na, locale, trim_ws, guess_integer)
if (eval){
args <- lapply(args, function(arg) {
if(is.character(arg))
eval(parse(text = arg, parent.frame(2)))
else
arg
})
}
list2env(args, envir = parent.frame())
invisible(NULL)
}
fun <- function(a, b, c, d){
convert_args()
dplyr::lst(a, b, c , d)
}
fun("NA","true","1","head(cars,2)")
#> Loading required namespace: readr
#> $a
#> [1] NA
#>
#> $b
#> [1] TRUE
#>
#> $c
#> [1] 1
#>
#> $d
#> [1] "head(cars,2)"
fun2 <- function(a, b, c, d){
convert_args(eval = TRUE, na = c("na","NA"))
dplyr::lst(a, b, c , d)
}
fun2("na","true","1","head(cars,2)")
#> $a
#> [1] NA
#>
#> $b
#> [1] TRUE
#>
#> $c
#> [1] 1
#>
#> $d
#> speed dist
#> 1 4 2
#> 2 4 10
由 reprex package (v0.3.0)
于 2019-06-21 创建
当使用包 shiny 或 plumber 处理用户输入时,通常需要将字符参数转换为数字或逻辑参数。
我想自动完成,有什么有效的方法吗?
预期(这个或类似):
convert_args <- ...
fun <- function(a, b, c, d){
convert_args()
dplyr::lst(a, b, c , d)
}
fun("na","true","1","foo")
#> $a
#> [1] NA
#>
#> $b
#> [1] TRUE
#>
#> $c
#> [1] 1
#>
#> $d
#> [1] "foo"
一种选择是使用 readr::parse_guess
,顾名思义,它会尝试猜测字符向量的类型。
convert_args <- function(x) {
lapply(x, readr::parse_guess)
}
convert_args(c("NA","true","1","foo"))
#[[1]]
#[1] NA
#[[2]]
#[1] TRUE
#[[3]]
#[1] 1
#[[4]]
#[1] "foo"
当我们有 "na"
readr::parse_guess("na")
#[1] "na"
但正如@Moody_Mudskipper 提到的,可以通过在 parse_guess
na
参数来解决
readr::parse_guess("na", c("na", "NA"))
#[1] NA
感谢@Ronak 的解决方案,我围绕 readr::parse_guess
构建了一个包装器以获得准确的预期输出。
我还添加了一个选项来评估未转换的字符输入,因为这也是一项常见任务。
convert_args <- function(na = c("", "NA"), locale = readr::default_locale(),
trim_ws = TRUE, guess_integer = FALSE, eval = FALSE){
if(!requireNamespace("readr"))
stop("convert_args() requires package readr to be installed")
args <- as.list(eval.parent(quote(match.call())))[-1]
args <- lapply(args, readr::parse_guess, na, locale, trim_ws, guess_integer)
if (eval){
args <- lapply(args, function(arg) {
if(is.character(arg))
eval(parse(text = arg, parent.frame(2)))
else
arg
})
}
list2env(args, envir = parent.frame())
invisible(NULL)
}
fun <- function(a, b, c, d){
convert_args()
dplyr::lst(a, b, c , d)
}
fun("NA","true","1","head(cars,2)")
#> Loading required namespace: readr
#> $a
#> [1] NA
#>
#> $b
#> [1] TRUE
#>
#> $c
#> [1] 1
#>
#> $d
#> [1] "head(cars,2)"
fun2 <- function(a, b, c, d){
convert_args(eval = TRUE, na = c("na","NA"))
dplyr::lst(a, b, c , d)
}
fun2("na","true","1","head(cars,2)")
#> $a
#> [1] NA
#>
#> $b
#> [1] TRUE
#>
#> $c
#> [1] 1
#>
#> $d
#> speed dist
#> 1 4 2
#> 2 4 10
由 reprex package (v0.3.0)
于 2019-06-21 创建