我已经以列表的形式定义了一个复杂的参数层次结构,提供了默认值,其中的属性定义了更多特征(在several.ok
中使用的示例match.args
)。我现在寻找一种方法将该列表与提供自定义的部分副本合并,并检查结果是否符合属性编码参数。如何实现这一目标(几个小时)。
请考虑以下事项:
defaults_list <- list(
a = structure('a', several.ok = TRUE),
b = list(
b1 = structure('b1', several.ok = TRUE),
b2 = structure('b2', several.ok = FALSE)))
partial_customization <- list(
b = list(
b2 = 'custom_b2'))
我正在寻找的是black_magic
,它将实现:
以递归方式合并列表,优先考虑partial_customization
和
使用示范several.ok
bool(FALSE
必须长度为1 - 在现实生活中测试所有结果元素&#39;我还有class
要检查的字段等。)
我从上面寻找的结果是:
result_list <- list(
a = 'a',
b = list(
b1 = 'b1',
b2 = 'custom_b2')
在
的情况下partial_customization <- list(
b = list(
b2 = c('custom_b2.1', 'custom_b2.2')))
由于several.ok
的{{1}}属性不允许b2
,因此应该抛出错误。
如何有效地做到这一点?
答案 0 :(得分:0)
通常情况下,解决方案实际上位于R
工具的核心集......
utils::modifyList
(几乎)我正在寻找(关于合并列表)。
作为原始函数条带属性,我修改了它如下:
modifyList_with_attributes <- function (x, val, keep.null = FALSE, maintain.x.attributes = TRUE)
{
stopifnot(is.list(x), is.list(val))
xnames <- names(x)
vnames <- names(val)
vnames <- vnames[nzchar(vnames)]
if (keep.null) {
for (v in vnames) {
saved_attributes <- attributes(x[[v]])
x[v] <- if (v %in% xnames && is.list(x[[v]]) && is.list(val[[v]]))
list(modifyList_with_attributes(x[[v]], val[[v]], keep.null = keep.null, maintain.x.attributes = maintain.x.attributes))
else val[v]
if(maintain.x.attributes)
{
attributes(x[[v]]) <- saved_attributes
}
}
}
else {
for (v in vnames) {
saved_attributes <- attributes(x[[v]])
x[[v]] <- if (v %in% xnames && is.list(x[[v]]) &&
is.list(val[[v]]))
modifyList_with_attributes(x[[v]], val[[v]], keep.null = keep.null, maintain.x.attributes = maintain.x.attributes)
else val[[v]]
if(maintain.x.attributes)
{
attributes(x[[v]]) <- saved_attributes
}
}
}
x
}