2014-01-29 62 views
2

我不知道我是否标有我的问题是正确的,但我给它一个镜头:R:如何使用省略号中的参数列表元素?

我想用一个包,它使用省略号,func(...)功能。我所有的类My_Class的论点都在列表中。由于我有很多争论,我想避免func(arg1, arg2, arg3)。所以理想情况下我想做func(my_list)。问题是功能看起来像这样

function(...) { 
    cl <- match.call(expand.dots = FALSE) 
    names <- lapply(cl[[2]],as.character) 
    ev <- parent.frame() 
    classes <- unlist(lapply(names,function(name){class(get(name,envir=ev))}))  
    if(!all(classes == "My_Class")) { 
    stop("an argument to ... is not a My_Class") 
    } 
} 

因此传递一个列表不起作用。

我也试过func(my_list[[1]], my_list[[2]])func(as.expression(my_list[[1]])),但即使它们不起作用。由于func将参数视为字符,func(my_list[[1]])变为chr [1:3] "[[" "my_list" "1"里面,和get(name,envir=ev)崩溃。我也试过do.call(func, my_list)但这次再次崩溃,因为my_list被评估,因此name里面的函数不再是character,而是My_CLass,又是get(name,envir=ev)崩溃。

所以我的问题:如何在不改变软件包/底层函数的情况下完成提交列表?我想写一个包装,但我卡住了,因为我甚至不能func(my_list[[1]])工作。也许我只是错过了我的问题的正确名称。

提前致谢!

+0

感谢您的回复速度快,但不要我要使用这里面FUNC()?我不想改变功能,即R包,而是编写脚本并按原样使用该功能。对不起,如果我没有正确理解。示例代码与my_list有什么关系? – Andarin

+1

评论消失的响应:'do.call(func,my_list)'导致'func'被'My_Class'对象调用,这是正确的。但是,测试写入的方式,它将'my_list'作为一个字符来获取名为get(name,envir = ev)'的对象,这不起作用。例如,通常你有'func(arg1)',如果'arg1'是'My_Class'对象,'func(arg1)'就可以工作。然后'func'得到(“arg1”,envir = ev)'这是有效的。如果'arg1 = 1',那么'do.call(fun,arg1)'会导致get(“1”,envir = ev)'不起作用。 – Andarin

+0

@RicardoSaporta,因为列表中的项目必须作为函数的'parent.frame'中的一个对象存在,所以不起作用。这个功能只是引人注目。 – BrodieG

回答

2

这工作,但我很困惑在该功能的设计选择:

lst <- list(
    a=structure(1:3, class="My_Class"), 
    b=structure(letters[1:3], class="My_Class") 
) 
env <- list2env(lst) 
call <- as.call(append(list(fun), names(lst))) 
eval(call, env) 

欺骗功能进入工作,你必须在你的列表中的项目是对象的环境,以评估它(是什么list2env做,创造那个环境)。

该功能的可怕之处在于,它根据名称查找parent.frame中的对象,并假定...的值确实是名称。我真的不明白为什么功能不只是这样做:

if(!all(vapply(list(...), class, "") == "My_Class")) stop(...) 
+0

非常感谢,它的工作原理!我正要写一个例子,但你速度更快。也感谢您的解释,也许我会建议。起初,我认为获得时间是用'match.call'而不是'list(...)',但是如果有人正在查找它们,它可能没有帮助。 – Andarin

+0

此外,意识到你甚至不需要创建一个环境;您可以直接使用列表作为'envir'参数进行评估。 – BrodieG

相关问题