2011-08-05 4 views
40

이것은 R 코드를 디버그하는 데 정말로 어려움이 있습니다.함수 안에 ddply가있는 객체를 찾을 수 없습니다.

순차적으로 명명 된 다른 열에 동일한 기능을 적용하려면 ddply()을 사용하고 싶습니다. 예. a, b, c. 이렇게하려면 열 이름을 문자열로 반복적으로 전달하고 함수에서 참조 할 수 있도록 eval(parse(text=ColName))을 사용합니다. 나는이 기술을 다른 대답에서 움켜 잡았다.

다른 함수 안에 ddply()을 넣기 전까지는 제대로 작동합니다. 다음은 샘플 코드입니다.

# Required packages: 
library(plyr) 

myFunction <- function(x, y){ 
    NewColName = "a" 
    z = ddply(x, y, summarize, 
      Ave = mean(eval(parse(text=NewColName)), na.rm=TRUE) 
    ) 
    return(z) 
} 

a = c(1,2,3,4) 
b = c(0,0,1,1) 
c = c(5,6,7,8) 
df = data.frame(a,b,c) 
sv = c("b") 

#This works. 
ColName = "a" 
ddply(df, sv, summarize, 
     Ave = mean(eval(parse(text=ColName)), na.rm=TRUE) 
) 

#This doesn't work 
#Produces error: "Error in parse(text = NewColName) : object 'NewColName' not found" 
myFunction(df,sv) 

#Output in both cases should be 
# b Ave 
#1 0 1.5 
#2 1 3.5 

아이디어가 있습니까? NewColName은 함수 안에서도 정의됩니다!

나는이 질문에 대한 대답을 loops-to-create-new-variables-in-ddply으로 도울 수 있다고 생각했지만 오늘은 머리를 두드리는 데 충분했다. 그리고 손을 들어 도움을 요청할 때가되었다.

답변

14

:

myFunction <- function(x,y){ 
NewColName <- "a" 
z <- do.call("ddply",list(x, y, summarize, Ave = call("mean",as.symbol(NewColName),na.rm=TRUE))) 
return(z) 
} 

myFunction(d.f,sv) 
    b Ave 
1 0 1.5 
2 1 3.5 
3

환경 문제가있는 것 같습니다. 글로벌 할당 문제를 해결하지만, 하나의 영혼의 비용 :

library(plyr) 

a = c(1,2,3,4) 
b = c(0,0,1,1) 
c = c(5,6,7,8) 
d.f = data.frame(a,b,c) 
sv = c("b") 

ColName = "a" 
ddply(d.f, sv, summarize, 
     Ave = mean(eval(parse(text=ColName)), na.rm=TRUE) 
) 

myFunction <- function(x, y){ 
    NewColName <<- "a" 
    z = ddply(x, y, summarize, 
      Ave = mean(eval(parse(text=NewColName)), na.rm=TRUE) 
    ) 
    return(z) 
} 

myFunction(x=d.f,y=sv) 

eval는 parent.frame 찾고있다 (1). 글로벌로 curenv 전달하는 데 여전히 한

가 이전 환경에서 my.parse을 꺼내 get을 사용하여
rm(NewColName) 
NewColName <- "a" 
myFunction <- function(x, y){ 

    z = ddply(x, y, summarize, 
      Ave = mean(eval(parse(text=NewColName)), na.rm=TRUE) 
    ) 
    return(z) 
} 
myFunction(x=d.f,y=sv) 

, 우리는 훨씬 더 가까이 올 수 있지만 : 대신의 MyFunction 외부 NewColName을 정의 그래서 경우에 작동합니다

myFunction <- function(x, y){ 
    NewColName <- "a" 
    my.parse <- parse(text=NewColName) 
    print(my.parse) 
    curenv <<- environment() 
    print(curenv) 

    z = ddply(x, y, summarize, 
      Ave = mean(eval(get("my.parse" , envir=curenv)), na.rm=TRUE) 
    ) 
    return(z) 
} 

> myFunction(x=d.f,y=sv) 
expression(a) 
<environment: 0x0275a9b4> 
    b Ave 
1 0 1.5 
2 1 3.5 

나는 ddplyparent.frame()sys.frame() 전략의 모든 I 실패 시도 이유입니다, 이미 .GlobalEnv에 평가하는 것으로 의심.

+0

솔루션에 @Hadley 기능이 필요할 수도 있습니다 :-) –

+0

이 모든 것을 시도해 볼 때 많은 노력이 필요합니다. 그룹의 머리를 두 드리는 것은 항상 감사합니다 ...... 나는 영혼을 지켜 드리겠습니다. –

9

내가 옆 단계에 문제를 단순히 summarize를 사용하지 않음으로써 경향이 다양한 환경을 탐색의 기능과 아웃을 신성 할만큼 똑똑하지, summarize 또는 transform 또는 뭔가 ddply을 결합하고 때 가끔이 같은 문제로 실행

분명히
myFunction <- function(x, y){ 
    NewColName <- "a" 
    z <- ddply(x, y, .fun = function(xx,col){ 
          c(Ave = mean(xx[,col],na.rm=TRUE))}, 
       NewColName) 
    return(z) 
} 

myFunction(df,sv) 

이 '수동'이 물건을에 비용이이지만, 종종 ddplysummarize을 결합에서 오는 평가 문제를 다루는의 두통을 피할 수 : 대신 내 자신의 익명 함수를 사용하여. 즉 ... 해들리 해결책으로 표시되지 않습니다 물론 것은 아니다

NewColName가 계속 표시입니다 당신은 환경에서 호출을 구성 do.callcall의 조합으로이 작업을 수행 할 수 있습니다
+2

버그를 해결할 때까지는 이것이 제가 권장하는 해결 방법입니다. 익명 함수 내에서'transform' 등을 사용할 수 있습니다. – hadley

+0

@joran 저는 솔루션을 구현했고 저에게 도움이되었습니다. 나는 왜 ddply에서이 범위 지정 문제가 있는지에 대해 호기심을 가졌습니다. 요약은 새 데이터 프레임을 만들고이 colName에 액세스 할 수 없기 때문에입니까? –

+0

@ user3801801 함수 인수를 대신하는 비표준 평가와 관련이 있습니다. 나는 특정 문제를 생각 나게하기 위해 소스 코드를 훑어보아야 할 것이다. 그러나 기본적으로 R은 어떻게 인수를 평가할 것인가와 관련이있다. (즉 현재의 인클로저 환경, 지구 환경, 어딘가에서 중에서). – joran

4

문제는 plyr 패키지 자체의 코드에 있습니다. 요약 함수에는 eval(substitute(...),.data,parent.frame()) 행이 있습니다. parent.frame()이 꽤 펑키하고 예기치 않은 것을 할 수 있다는 것은 잘 알려져 있습니다. T

그는 @James의 해결책은 매우 좋은 해결 방법 인 입니다.하지만 그 전에는 해들리 자신이 plyr 패키지가 기능 내에서 사용되도록 의도되지 않았다고 말한 것을 기억한다면.

죄송합니다. 여기 잘못되었습니다. 그것은 현재 알려져 있지만, plyr 패키지는 이러한 상황에서 문제를 일으 킵니다. 이 질문에

myFunction <- function(x, y){ 
    NewColName = "a" 
    z = aggregate(x[NewColName],x[y],mean,na.rm=TRUE) 
    return(z) 
} 
> myFunction(df,sv) 
    b a 
1 0 1.5 
2 1 3.5 
+0

+1 나의 "avoid"summarize "해결책을 취하고 문제에 대한 실제 설명을 제공하십시오. ;) – joran

+0

+1은 parent.frame() 문제를 설명하는 데 시간을 할애 한 분입니다. 함수가 연속 된 코드를 작성해야하기 때문에 다른 함수에서 함수를 사용할 수 없다는 것이 이상하게 보입니다. 어쩌면 @ 해들리가 논평 할 수 있습니다. –

+0

필자는 plyr이 함수 내에서 사용되도록 의도되지 않았다고 결코 확신하지 못했습니다. 저는 항상 이것이 현재 버그를 수정해야한다고 말했습니다. ( – hadley

22

오늘의 솔루션은 here(summarize)summarize를 만드는 것입니다 :

따라서, 나는 당신에게 문제에 대한 기본 솔루션을 제공합니다. 예 :

myFunction <- function(x, y){ 
    NewColName = "a" 
    z = ddply(x, y, here(summarize), 
      Ave = mean(eval(parse(text=NewColName)), na.rm=TRUE) 
    ) 
    return(z) 
} 

here(f)

는 12 월 2012 년 현재 컨텍스트를 캡처 plyr 첨가.

+0

Brilliant! lubridate와 plyr을 함께 사용하는 경우 특별히 plyr :: here()를 참조하십시오 (불행히도 여기에 윤곽을 그리기 때문에()) –

+0

자세한 정보 : https://github.com/hadley/plyr/ 문제/3 – Lennert

관련 문제