从索引中获取列表元素名称
Get list element name from index
我正在尝试使用以下 glue
代码来创建信息性错误消息
library(rlang)
library(glue)
my_function <- function(x) {
UseMethod("my_function", x)
}
my_function.default <- function(x) {
abort(glue(
"Can't calculate my_function because { deparse(substitute(x)) } is of type ",
glue_collapse(class(x))
))
}
使用这个测试列表我们看到它有效:
test <- list(
x = c(1,2,3),
y = c("one", "two", "three")
)
my_function(test[[1]])
Error: Can't calculate my_function because test[[1]] is of type numeric
Run `rlang::last_error()` to see where the error occurred.
但是是否可以使用 glue
来获得错误 return x
,其中显示 test[[1]]
导致错误:
Can't calculate my_function because x is of type numeric
这是一个深入索引表达式以推断被索引元素名称的函数。简而言之,它将遵循 list[index]
模式的表达式转换为 names(list)[index]
,同时智能地处理 list$name
已经在表达式中具有名称。
getElementNames <- function(ee) {
## Determine if ee is an indexing operation
eel <- as.list(ee)
isIdx <- purrr::map_lgl(exprs( `[`, `[[`, `$` ),
identical, eel[[1]])
## If not, return the expression itself as a string
if(!any(isIdx)) return( deparse(ee) )
## The name may already be in the expression
if( is.name(eel[[3]]) || is.character(eel[[3]]) )
return( as.character(eel[[3]]) )
## Compose an expression indexing the names
nms <- eval.parent(expr( names(!!eel[[2]])[!!eel[[3]]] ))
## Names might be missing
`if`( is.null(nms), deparse(ee), nms )
}
实际函数:
test <- list(a=4, b=5, c=6)
test2 <- 1:3
ftest <- function(x) abort(glue("Can't calculate {getElementNames(substitute(x))}"))
ftest( test[[2]] ) # index by numeric value
# Error: Can't calculate b
ftest( test$c ) # index by name
# Error: Can't calculate c
ftest( test[["a"]] ) # another way to index by name
# Error: Can't calculate a
i <- 2; j <- 3
ftest( test[i:j] ) # index multiple elements
# Error: Can't calculate b
# * Can't calculate c
ftest( test2[3] ) # index something with no names
# Error: Can't calculate test2[3]
ftest( fun_that_returns_list() ) # non-indexing expression
# Error: Can't calculate fun_that_returns_list()
ftest( 1:3 ) # another non-indexing expression
# Error: Can't calculate 1:3
我正在尝试使用以下 glue
代码来创建信息性错误消息
library(rlang)
library(glue)
my_function <- function(x) {
UseMethod("my_function", x)
}
my_function.default <- function(x) {
abort(glue(
"Can't calculate my_function because { deparse(substitute(x)) } is of type ",
glue_collapse(class(x))
))
}
使用这个测试列表我们看到它有效:
test <- list(
x = c(1,2,3),
y = c("one", "two", "three")
)
my_function(test[[1]])
Error: Can't calculate my_function because test[[1]] is of type numeric
Run `rlang::last_error()` to see where the error occurred.
但是是否可以使用 glue
来获得错误 return x
,其中显示 test[[1]]
导致错误:
Can't calculate my_function because x is of type numeric
这是一个深入索引表达式以推断被索引元素名称的函数。简而言之,它将遵循 list[index]
模式的表达式转换为 names(list)[index]
,同时智能地处理 list$name
已经在表达式中具有名称。
getElementNames <- function(ee) {
## Determine if ee is an indexing operation
eel <- as.list(ee)
isIdx <- purrr::map_lgl(exprs( `[`, `[[`, `$` ),
identical, eel[[1]])
## If not, return the expression itself as a string
if(!any(isIdx)) return( deparse(ee) )
## The name may already be in the expression
if( is.name(eel[[3]]) || is.character(eel[[3]]) )
return( as.character(eel[[3]]) )
## Compose an expression indexing the names
nms <- eval.parent(expr( names(!!eel[[2]])[!!eel[[3]]] ))
## Names might be missing
`if`( is.null(nms), deparse(ee), nms )
}
实际函数:
test <- list(a=4, b=5, c=6)
test2 <- 1:3
ftest <- function(x) abort(glue("Can't calculate {getElementNames(substitute(x))}"))
ftest( test[[2]] ) # index by numeric value
# Error: Can't calculate b
ftest( test$c ) # index by name
# Error: Can't calculate c
ftest( test[["a"]] ) # another way to index by name
# Error: Can't calculate a
i <- 2; j <- 3
ftest( test[i:j] ) # index multiple elements
# Error: Can't calculate b
# * Can't calculate c
ftest( test2[3] ) # index something with no names
# Error: Can't calculate test2[3]
ftest( fun_that_returns_list() ) # non-indexing expression
# Error: Can't calculate fun_that_returns_list()
ftest( 1:3 ) # another non-indexing expression
# Error: Can't calculate 1:3