从索引中获取列表元素名称
Posted
技术标签:
【中文标题】从索引中获取列表元素名称【英文标题】:Get list element name from index 【发布时间】:2020-07-27 15:38:14 【问题描述】:我正在尝试使用以下 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
来让错误返回x
,它说test[[1]]
导致错误:
Can't calculate my_function because x is of type numeric
【问题讨论】:
我希望它返回列表元素的名称,所以如果我现在执行 my_function(test[[2]]) 它将返回“无法计算 my_function,因为 y 是字符类型” 你想要列表元素的名字 当您传入test[[1]]
时,您也不会传入名称。你可以编写代码来处理这个问题,但是你也可以为my_function(test$x)
或my_function(fun_that_returns_list())
或my_function(1:3)
这样的情况编写特殊代码——在这些情况下会发生什么?如果您总是期望一个列表,那么您可能需要为列表本身和子集参数指定单独的参数。
如果在里面是不可能的。您可以传递两个参数,一个是列表和名称,这样会更容易
R 中任何类型的正常评估都不可能。值不知道它们在列表中的事实。只有列表知道它们的值的情况。
【参考方案1】:
这是一个挖掘索引表达式以推断被索引元素的名称的函数。简而言之,它将遵循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
【讨论】:
以上是关于从索引中获取列表元素名称的主要内容,如果未能解决你的问题,请参考以下文章
如何从列表“StandardListItem”中的 JSON 文件中的元素“名称”中获取所有值?