[r] 큰 R 프로그램을 구성하는 방법?
복잡한 R 프로젝트를 수행하면 스크립트가 길고 혼란스러워집니다.
내 코드가 항상 즐겁게 사용할 수 있도록 채택 할 수있는 몇 가지 방법은 무엇입니까? 나는 같은 것들에 대해 생각하고있다
- 소스 파일에 함수 배치
- 다른 소스 파일로 무언가를 나눌 때
- 마스터 파일에 있어야 할 것
- 기능을 조직 단위로 사용 (R이 전역 상태에 액세스하기 어려운 경우 가치가 있는지 여부)
- 들여 쓰기 / 줄 바꿈 관행.
- 치료 ({?
- 1) 또는 2 줄에)} 같은 것을 넣습니까?
기본적으로 큰 R 스크립트를 구성하기위한 규칙은 무엇입니까?
답변
표준 답변은 패키지를 사용 하는 것입니다. 웹에서 다른 자습서는 물론 Writing R Extensions 설명서를 참조하십시오 .
그것은 당신에게 제공
- 주제별로 코드를 구성하는 준 자동 방법
- 도움말 파일을 작성하여 인터페이스에 대해 생각할 것을 강력히 권장합니다.
- 통해 많은 위생 검사
R CMD check
- 회귀 테스트를 추가 할 수있는 기회
- 네임 스페이스를위한 수단뿐만 아니라
source()
코드를 실행 하면 실제로 짧은 스 니펫에 효과적입니다. 내부 리포지토리 용 내부 패키지를 작성할 수 있으므로 게시 할 계획이 없더라도 다른 모든 것은 패키지에 있어야합니다.
‘편집 방법’부분에 대해서는 R Internals 매뉴얼 에 섹션 6의 우수한 R 코딩 표준 이 있습니다. 그렇지 않으면 Emacs의 ESS 모드 에서 기본값을 사용하는 경향이 있습니다 .
2008-Aug-13 업데이트 : David Smith가 Google R 스타일 가이드에 대해 블로그에 올렸습니다 .
답변
나는 다른 기능을 자신의 파일에 넣는 것을 좋아합니다.
그러나 나는 R의 패키지 시스템을 좋아하지 않는다. 사용하기가 다소 어렵습니다.
파일 기능을 환경 내에 배치하고 (다른 모든 언어는 “네임 스페이스”라고 부르는) 대체 파일을 선호합니다. 예를 들어, ‘util’기능 그룹을 다음과 같이 만들었습니다.
util = new.env()
util$bgrep = function [...]
util$timeit = function [...]
while("util" %in% search())
detach("util")
attach(util)
이것은 모두 util.R 파일에 있습니다 . 당신이 그것을 소싱 할 때, 당신은 호출 할 수있는 환경 ‘유틸리티’를 얻습니다 util$bgrep()
. 더 나아가서, 그 attach()
부름은 그렇게 정당 bgrep()
하고 그러한 일을 직접적으로 만듭니다. 이러한 함수를 모두 자신의 환경에 두지 않은 경우 통역사의 최상위 네임 스페이스 (오른쪽 네임 스페이스)를 오염시킵니다.ls()
됩니다.
모든 파일이 모듈 인 Python의 시스템을 시뮬레이션하려고했습니다. 그것은 더 나을 것이지만 이것은 괜찮은 것 같습니다.
답변
프로그래머라면 특히 분명하게 들릴지 모르지만, 논리적이고 물리적 인 코드 단위에 대한 생각은 다음과 같습니다.
이것이 귀하의 경우인지 모르겠지만 R에서 일할 때 큰 복잡한 프로그램을 염두에 두지 않습니다. 나는 보통 하나의 스크립트에서 시작하여 코드를 논리적으로 분리 가능한 단위로 분리하며 종종 함수를 사용합니다. 데이터 조작 및 시각화 코드는 자체 기능 등에 배치됩니다. 이러한 기능은 파일의 한 섹션에 그룹화됩니다 (맨 위의 데이터 조작, 시각화 등). 궁극적으로 스크립트를보다 쉽게 유지 관리하고 결함 비율을 낮추는 방법에 대해 생각하고 싶습니다.
미세하고 거칠게 기능을 만드는 방법은 다양하고 다양한 규칙이 있습니다. 예를 들어 15 줄의 코드 또는 “이름으로 식별되는 하나의 작업을 수행하는 기능”등이 있습니다. 마일리지는 다양합니다. . R은 참조 별 호출을 지원하지 않기 때문에 일반적으로 데이터 프레임이나 유사한 구조를 전달할 때 함수를 너무 세분화하는 방법이 다양합니다. 그러나 이것이 R을 처음 시작할 때 바보 같은 성능 오류에 대한 과도한 보상 일 수 있습니다.
논리 단위를 자체 물리 단위 (예 : 소스 파일 및 패키지와 같은 더 큰 그룹화)로 추출 할 때는 언제입니까? 두 가지 경우가 있습니다. 첫째, 파일이 너무 커지고 논리적으로 관련이없는 단위 사이를 스크롤하면 성가신 일입니다. 둘째, 다른 프로그램에서 재사용 할 수있는 기능이 있다면. 일반적으로 데이터 조작 기능과 같은 그룹화 된 단위를 별도의 파일에 배치하여 시작합니다. 그런 다음 다른 스크립트에서이 파일을 제공 할 수 있습니다.
함수를 배포하려면 패키지에 대한 생각을 시작해야합니다. 프로덕션에 R 코드를 배포하거나 다양한 이유로 다른 사람들이 재사용하기 위해 배포하지 않습니다 (간결하게 : 조직 문화는 다른 언어를 선호하고 성능, GPL 등). 또한 소스 파일 모음을 지속적으로 수정하고 추가하는 경향이 있으며 변경을 할 때 패키지를 다루지 않습니다. 따라서 더 자세한 내용은 Dirk와 같은 다른 패키지 관련 답변을 확인해야합니다.
마지막으로, 귀하의 질문이 R에만 국한되는 것은 아니라고 생각합니다. Steve McConnell의 Code Complete를 읽고 이러한 문제와 코딩 방법에 대한 많은 지혜가 담긴 코드를 읽는 것이 좋습니다.
답변
Dirk의 조언에 동의합니다! 간단한 스크립트에서 문서화 된 패키지로 프로그램을 구성하는 IMHO는 R에서 프로그래밍하는 경우 쓰기를 위해 Word에서 TeX / LaTeX로 전환하는 것과 같습니다. 매우 유용한 R 패키지 만들기 : Friedrich Leisch 의 자습서 를 살펴 보는 것이 좋습니다 .
답변
나의 간결한 답변 :
- 일반적인 충분한 출력 및 입력을 식별하여 기능을 신중하게 작성하십시오.
- 전역 변수의 사용을 제한하십시오.
- S3 객체 및 적절한 경우 S4 객체를 사용하십시오.
- 특히 함수가 C / Fortran을 호출 할 때 패키지에 함수를 넣습니다.
R은 프로덕션 환경에서 점점 더 많이 사용되므로 재사용 가능한 코드의 필요성은 이전보다 훨씬 큽니다. 통역사가 이전보다 훨씬 더 견고하다는 것을 알았습니다. R이 C보다 100-300x 느리다는 것은 의심의 여지가 없지만 일반적으로 병목 현상은 몇 줄의 코드에 집중되어 있으며 C / C ++에 위임 할 수 있습니다. 데이터 조작 및 통계 분석에서 R의 강점을 다른 언어로 위임하는 것은 실수라고 생각합니다. 이러한 경우 성능 저하가 적고 어쨌든 개발 노력을 절감 할 가치가 있습니다. 실행 시간만으로도 문제가되지 않으면 모두 어셈블러를 작성해야합니다.
답변
패키지를 작성하는 방법을 알아 내려고했지만 시간을 투자하지 않았습니다. 각각의 미니 프로젝트에 대해 모든 하위 수준 기능을 ‘functions /’라는 폴더에 보관하고 명시 적으로 만든 별도의 네임 스페이스로 소싱합니다.
다음 코드 줄은 검색 경로에 “myfuncs”라는 환경이 아직없는 경우 (연결을 사용하여) 환경을 만들고 내 ‘functions /’디렉토리의 .r 파일에 포함 된 함수로 채 웁니다 ( sys.source). 나는 보통이 줄들을 메인 스크립트의 맨 위에 놓는다. “사용자 인터페이스”는 높은 수준의 함수 (낮은 수준의 함수 호출)가 호출되는 “사용자 인터페이스”를 의미한다.
if( length(grep("^myfuncs$",search()))==0 )
attach("myfuncs",pos=2)
for( f in list.files("functions","\\.r$",full=TRUE) )
sys.source(f,pos.to.env(grep("^myfuncs$",search())))
변경할 때 항상 같은 줄을 사용하여 소스를 변경하거나 다음과 같은 것을 사용할 수 있습니다
evalq(f <- function(x) x * 2, pos.to.env(grep("^myfuncs$",search())))
생성 한 환경에서 추가 / 수정을 평가합니다.
내가 아는 것은 끔찍한 일이지만 그것에 대해 너무 공식적이 될 필요는 없습니다 (그러나 패키지 시스템을 장려 할 수 있다면 장래에 그 방식으로 마이그레이션 할 것입니다).
코딩 규칙에 관해서는 이것이 미학에 관해 내가 본 유일한 것입니다 (나는 그것들을 좋아하고 느슨하게 따르지만 R에서 너무 많은 중괄호를 사용하지는 않습니다) :
http://www1.maths.lth.se/help/R/RCC/
[, drop = FALSE]와 <-의 사용에 관한 다른 “수집”이 useR에서 다양한 프레젠테이션 (보통 기조 연설)에서 제안한 것처럼! 컨퍼런스이지만,이 중 어느 것도 엄격하다고 생각하지 않습니다 ([, drop = FALSE]는 예상 한 입력을 확신하지 못하는 프로그램에 유용합니다).
답변
패키지를 선호하는 다른 사람으로 나를 계수하십시오. 필자는 필요할 때 (즉, 릴리스 될 때까지) 맨 페이지와 비 네트를 작성하는 데 꽤 나쁘다는 것을 인정하지만 소스 도우를 묶는 정말 편리한 방법을 만듭니다. 또한 코드 유지 관리에 대해 진지하게 생각하면 Dirk이 제기하는 모든 점이 plya에 도달합니다.