在R中,可以使用$
访问列表元素。当访问未包含在列表中的字段时,结果值仅为 NULL
。这在我的代码中我进一步处理对象的部分中是有问题的。取以下代码:
l <- list(foo = 1, bar = 2)
print(l$foobar)
输出将只是NULL
,没有错误和警告。我知道这可能需要,以便分配新元素(l$foobar <- 3
(可以工作。
,有没有办法使对字段的读取访问成为硬错误?
一个极端的选择是重载 $
运算符,然后为检查名称的列表对象定义一个 S3 方法。
`$` <- function(x, y) {
UseMethod("$")
}
`$.list` <- function(x, y) {
ylab <- deparse(substitute(y))
stopifnot(ylab %in% names(x))
do.call(.Primative("$"), list(x, ylab))
}
然后:
myList <- list('a' = pi)
> myList$b
Error: ylab %in% names(x) is not TRUE
> myList$a
3.141593
当然,您必须确保设置以下内容:
`$.default` <- base::`$`
避免与"$"运算符的现有用法发生任何冲突
如果您希望在应用于列表时继续使用带有"$"的部分匹配,则可以使用 stopifnot(length(pmatch(ylab, names(x)))>0)
。
古老的问题,已经接受了编写自定义函数的答案,但我认为base
R 的get
也应该可以解决问题:
l <- list(foo = 1, bar = 2)
get('foobar', l)
#> Error in get("foobar", l): object 'foobar' not found
您可以尝试编写自己的函数:
extract_ls <- function(ls, el){
if (!el %in% names(ls)) stop(paste0("The specified element ", el, " does not exist in the list"))
else return(ls[[el]])
}
然后你可以做:
extract_ls(l, "baz")
#Error in extract_ls(l, "baz") :
# The specified element baz does not exist in the list
extract_ls(l, "bar")
#[1] 2
请注意,我使用 [[
而不是 $
。这两者执行相同的操作,但$
执行部分匹配。此外,[[
需要一个字符串。
要使其成为中缀函数,只需将函数名称更改为 `%[[%`
。然后用法是:
l %[[% "baz"
#Error in l %[[% "baz" :
# The specified element baz does not exist in the list
l %[[% "bar"
#[1] 2
试试这个
el_names <- function(l,variable)
{
if(is.null(l[[variable]]) & length(l)>1)
{
stop("Null found")
}
else{
print(l[[variable]])
}
}
> el_names(l,"foo")
[1] 1