2013-02-14 3 views
21

개체 이름 바꾸기와 @Shane의 대답에 대해 this basic question을 읽었습니다. 나를 게으른 평가로 보았습니다. 이제 assign이 느리게 평가되는지 궁금합니다. 그냥 여기처럼 : 나는 이것에 대해 궁금해하는 이유R의 지연 평가 - 영향을 받습니까?

assign("someNewName",someOldObject) 
rm(someOldObject) 

이유는 다음과 같은 사용 사례입니다 : 내가 10K + R 객체를 각각의 originalNameadditionalName라는 두 가지 속성을 가지고있어 가정합니다. 이제는 사용자가이 두 속성을 잃지 않고 한 이름에서 다른 이름으로 효율적으로 전환 할 수있는 함수를 작성하려고합니다. 대략 이렇게 ...

EDIT : @ Hadley의 입력에 따라 코드가 변경되었습니다.

switchObjectName <- function(x) { 
    n1 <- attributes(x)$originalName 
    n2 <- attributes(x)$additionalName 
    objName <- deparse(substitute(x)) 
    if(objName == n1) { 
    delayedAssign(n2,x,assign.env=.GlobalEnv) 
    } else { 
    delayedAssign(n1,x,assign.env=.GlobalEnv) 
    } 
    rm(list=c(objName),envir=.GlobalEnv)  
} 

이 잘 작동하지만 난 rm 문 권리를 얻기 위해 매우 몇 가지 문제가 있었다. 나는 rm(objName,envir=.GlobalEnv)을 시도했으나 objName이 문자가 아니기 때문에 결과적으로 deparse(substitute(x)이라는 결과를 얻지 못했습니다.

+12

질문을 올바르게 이해하면 'delayedAssign', https://github.com/hadley/pryr/blob/master/R/assign-delayed.r 및'배정 : 값에 이름 연결 '섹션을 참조하십시오. 다시 한 번 감사드립니다. https://github.com/hadley/devtools/wiki/environments – hadley

+0

. 특히 위키에있는 장의 포인터가 실제로 진행되는 것을 이해하는 데 많은 도움이되었습니다. 'delayedAssign'은 옳은 힌트였습니다. –

답변

5

R 언어는 일반적으로 값 의미을가집니다. 할당 x <- yxy이 동일한 개체의 독립적 인 복사본이라는 것을 의미합니다 (yx의 업데이트는 독립적입니다). x <- y의 순진한 구현은 항상 x에 메모리를 할당하고 y을 완전히 복사합니다. GNU-R은 copy-on-write 메커니즘을 대신 사용하여 업데이트가 실제로 일어날 때까지 복사본을 연기하여 메모리/실행 시간을 절약합니다. R 사용자는이 최적화에 대해 알 필요가 없으며 메모리가 부족한 경우를 제외하고는 완전히 투명합니다. 이 메커니즘은 x <- yassign("x", y)으로 똑같이 쓰여진 할당에 적용됩니다.

게으른 평가은 언어 디자인의 일부이며 R 사용자/프로그래머에게 표시됩니다. 표현식이 함수에 인수로 전달되었습니다. foo(ls())에서 전달 된 표현식은 ls()이며, 호출 된 함수의 구현이 필요할 때만 지연 평가됩니다.

delayedAssign은 R 사용자/프로그래머가 볼 수있는 저수준 함수이지만 실제로는 패키지의 지연로드에만 사용되며 사용자 프로그램에 필요하지 않아야합니다. delayedAssign 변수의 값을 계산하는 식을 지정할 수 있습니다. 변수가 처음으로 읽혀질 때만 계산이 지연됩니다.

그래서 질문에 대답하기 위해 R에서의 할당은 copy-on-write 메커니즘이 사용된다는 점에서 항상 '게으른'것입니다. 할당의 오른쪽의 계산은 (delayedAssign을 사용하는) 게으른 수 있지만 사용자 프로그램에서 필요하지 않거나 사용해서는 안됩니다.

변수의 '이름 바꾸기'에 대해서는 delayedAssign을 사용할 필요가 없습니다. 왜냐하면 오른쪽이 계산되지 않기 때문입니다. 상황을 더욱 복잡하게 만들고 서적 보관으로 인해 성능 오버 헤드가 발생할 수 있습니다. delayedAssign이 있습니다. 변수 이름을 변경해야한다면 일반 할당을 사용합니다.

코드 명확성을 위해 가능하면 언제든지 환경 변수를 삭제하거나 기능에서 전역 환경으로 할당하는 것을 피하는 것이 좋습니다. 난 그냥 새 목록을 만들고 그것에 새로운 바인딩 (변수)를 삽입합니다.

GNU-R의 현재 구현과 관련하여 설명한 솔루션 중 하나라도 변수의 이름이 변경되지 않은 경우 필요하지 않은 메모리 복사가 발생할 수 있습니다. 이것을 R 레벨에서 피할 방법이 없습니다.

관련 문제