2014-01-29 1 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)'는'My_Class' 객체로'func'가 호출되는 결과를 낳습니다. 그러나 테스트가 작성된 방식으로,'my_list'를 문자로 취급하여 작동하지 않는'get (name, envir = ev)'이름으로 객체를 가져옵니다. 예를 들어, 보통 'arg1'이 'My_Class' 객체 인 경우 작동하는'func (arg1)'이 있습니다. 그러면'func'은'get ("arg1", envir = ev)'을 실행합니다. 'arg1 = 1'이라면'do.call (fun, arg1)'은'get ("1", envir = ev)'로 끝난다. – Andarin

+0

@RicardoSaporta, 목록의 항목이 함수의 'parent.frame'에있는 객체로 존재해야하기 때문에 @RicardoSaporta가 작동하지 않습니다. 이 기능은 단지 마음 만 먹는 것입니다. – 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

고마워, 작동 해! 나는 예제를 쓰려고했지만 당신은 더 빨랐다. 그리고 설명을 해줘서 고마워, 아마 내가 제안 할 것이다. 처음에는'list (...) '대신에'match.call'이 사용되는 시간을 얻는다고 생각했지만, 어쨌든 그것을 찾으면 도움이되지 않을 수도 있습니다. – Andarin

+0

또한 환경을 만들지 않아도된다는 것을 깨닫습니다. 리스트를'envir' 인수로서 직접 평가할 수 있습니다. – BrodieG