본문으로 바로가기



Make your own R package! - 5. Imports, Suggests, and README.Rmd 에 대하여

category R Programming/Rpackage 2017.07.08 14:41
Make your own R package! - 5. Imports, Suggests, and README.rmd

저번 포스팅을 통해서 필자는 roxygen2 패키지를 사용하여 자동으로 man 폴더와 NAMESPACE 파일을 관리하는 방법에 대하여 알아보았다. 오늘 배울 내용은 우리의 패키지를 만드는 과정에서 다른 패키지들에 존재하는 함수를 빌려서 사용하는 방법을 알아보자.

mle_gamma() 함수

현재 필자의 r4issactoast 패키지에는 mom_gamma() 함수가 들어있다. 이번 포스팅에서는 mle_gamma() 함수를 예로 설명해보도록 하겠다. 왜냐하면 mle_gamma() 함수는 아래의 코드와 같이 R의 stats 패키지의 uniroot() 함수를 사용해서 정의되었기 때문이다. 함수에 관한 설명은 감마함수 MLE 포스팅을 참고하자.

mle_gamma <- function(sample_g){
    # calculate MOME as an initial value
    x_bar  <- mean(sample_g)
    x2_bar <- mean(sample_g^2)
    mom_theta <- (x2_bar - x_bar^2) / x_bar
    mom_k <- x_bar / mom_theta
    
    # equation for k
    f <- function(k){ mean(log(sample_g)) -
                                log(mean(sample_g)/k) -  digamma(k)}
    # mle
    mle_k <- uniroot(f, mom_k + c(-2, 2))
    mle_theta <- mean(sample_g) * (1 / mle_k$root)
    
    # result
    c(k_hat = mle_k$root, theta_hat = mle_theta)
}

일단 지난 시간의 지식을 가지고 mle_gamma() 함수를 업데이트 시켜보자.

    1. 일단 위의 코드를 패키지의 R폴더에 적당한 이름의 R파일을 만들어 붙여넣기를 한다. 필자의 경우 이전 포스팅에서 만들었던 inference.R 파일을 이어서 사용하도록 하겠다.
    1. 지난번 mom_gamma() 함수와 비슷하게 roxygen 태그를 이용하여 함수 정보를 입력하도록 하자.
#' Maximum Likelihood Estimator for gamma dist.
#'
#' mle_gamma function will calculate mle estimate for the shape parameter
#' "k" and the scale parameter "theta" by using given sample. Since there is no closed form of the mle for gamma distribution, mle_gamma used uniroot function from stats package.
#'
#' @param sample_g the given sample to calculate the estimate of the parameters.
#' @return A 2 by 1 vector containing estimate of parameters k and theta: c(k_hat, theta_hat)
#' @examples
#'   my_sample <- rgamma(50, shape = 2, scale = 3)
#'   mle_gamma(my_sample)
#' @export
    1. devtools 패키지의 document() 함수를 콘솔창에 입력한다. 이를 통하여 NAMESPACE와 man폴더를 업데이트 해주는 것이다.
    1. 업데이트가 잘 되었는지 build 탭에 check 버튼을 누르도록 하자.

패키지 체크를 해보면 아래와 같은 화면이 뜰 것이다.

check 메세지 - uniroot함수에 관한 note가 생긴다.

이러한 노트가 뜨는 이유는 앞서 말했던 것처럼 uniroot 함수가 우리가 만든 패키지에서 나온 함수가 아닌 stats 패키지 즉, 우리가 만드는 패키지(필자의 경우 r4issactoast) 밖에서 정의된 함수이기 때문이다. 따라서 이렇게 패키지 밖에서 함수를 불러올 때는 어느 패키지에 정의된 함수 인지를 NAMESPACE에 명시해 주어야 한다. 또한 만약 특정 패키지가 현재 만들고 있는 패키지와 밀접하게 연관이 되어있을 경우, 패키지 설치시 같이 설치되도록 만들어야 패키지가 원활하게 작동할 것이다. 이러한 부분을 설정해주기 위하여 다음의 두 가지를 사용할 수 있다.

  1. roxygen에서는 import 태그를 사용하여 어떤 패키지에 속한 어떤 함수를 불러와야하는지에 대한 정보를 표시한다. 혹은,

  2. 코드 안에서 함수를 정의할 경우, library() 명령어를 사용하는 대신, 패키지명::함수() 형태의 명령어를 사용한다.

따라서 위의 정의된 mle_gamma() 함수의 코드에 다음과 같은 roxygen 태그, 혹은 패키지 지정 명령어 ::를 추가하도록 하자.

# add roxygen tag
    #' @importFrom stats uniroot
# or
# add 'stats::' code before uniroot 
    # mle
    mle_k <- stats::uniroot(f, mom_k + c(-2, 2))

위의 코드들을 추가하고, devtools::document() 명령어를 다시 한번 실행시키면, NAMESPACE의 파일의 내용에 importFrom(stats,uniroot) 부분이 추가됨을 확인 할 수 있다. 이제 다시 체크 기능을 사용해서 확인해보면 note가 사라졌음을 확인 할 수 있을 것이다.

DESCRIPTION 파일 수정 - Imports 와 Suggests

stats 패키지는 R에 기본적으로 설치되어있는 기본 패키지 중 하나이다.

getOption("defaultPackages")
## [1] "datasets"  "utils"     "grDevices" "graphics"  "stats"     "methods"

따라서 사용자가 필자의 r4issactoast를 설치했을 경우, 모든 사용자는 일부러 지우지 않은 이상 stats패키지를 가지고 있을 것이고, 필자의 패키지를 실행시키는데에 이상이 없을 것이다. 하지만, 만약 빌려쓰는 함수가 stats 패키지처럼 기본적으로 깔려있는 패키지가 아니라면, DESCRIPTION 파일의 내용도 반영해 줘야한다.

예를들어, 필자가 만든 R4Tistory의 경우, rmarkdown 패키지의 render함수를 import해서 사용하는데, 이 경우는 NAMESPACE의 내용 뿐 아니라 DESCRIPTION 파일에 다음과 같은 항목이 추가되어 있다.

Imports:
  httr,
  rmarkdown
Suggests: knitr

Imports 태그와 Suggests 태그는 중요도에 차이가 있다. Imports 태그는 필자의 패키지가 Imports 태그에 속한 패키지들이 없으면 작동을 하지 않음을 의미한다. 반면, Suggests에 속한 패키지들은 있으면 좋지만, 패키지의 주요 기능을 수행하는데에는 이상이 없는 패키지들이라는 것을 의미한다.

r4issactoast 패키지의 경우, stats패키지가 없다면, 사용자는 mle_gamma() 함수를 실행하지 못하므로, r4issactoast를 설치할 때 사용자가 stats패키지가 설치되어 있는지 체크하고, 없는 경우 설치를 할 수 있도록 DESCRIPTION 파일에 Imports 목록란에 반영시켜주자. devtools 패키지는 use_package() 함수를 제공하여 이러한 imports와 suggests 관리를 쉽게 만들어준다.

# Imports
devtools::use_package("stats")

# For adding package as Suggests
# devtools::use_package("stats", type = "Suggests")

Version 명시

우리가 작성한 패키지가 어떠한 환경에서 개발이 되었는지 사용자에게 알려주는 것을 중요하다. 왜냐하면 패키지를 다운받은 사용자의 작업환경이 개발시 작업한 환경과 다르다면, 패키지가 정상적으로 동작하지 않을 수 있기 때문이다. 따라서 자신의 현재 R버전과 패키지에 사용된 버전을 다음의 명시해주도록 하자.

# R version
Depends: R (>= 3.4.1)

# For packages,
Imports:
  stats (>= 3.4.1)

설정을 마친 뒤 Build 탭에서 build & reload 와 check 버튼을 눌러 패키지를 확인한다. 최종 설정을 마친 ’r4issactoast’의 DESCRIPTION파일의 내용은 다음과 같다.

Package: r4issactoast
Type: Package
Version: 0.1.0
Date: 2017-07-05
Title: Favorite R Functions for <www.issactoast.com>
Authors@R: c(person("Issac", "Lee", role = c("aut", "cre"),
                     email = "issactoast@gmail.com"))
Description: This package has many functions which are used
    in <www.issactoast.com> blog''s statistics posts. All the explations
    and applications of functions can be found in the website given in the title.
License: MIT + file LICENSE
Encoding: UTF-8
RoxygenNote: 6.0.1
Depends: R (>= 3.4.0)
Imports: 
  stats (>= 3.4.0)

README.Rmd 파일을 사용한 README.md 관리

이제 함수를 추가하였으니, 깃허브에 올려놓을 차례인데, 이번에는 README.md 파일에 내용을 추가해보도록 하자. 다음의 명령어를 입력한다.

devtools::use_readme_rmd()

위의 명령어를 입력하면 패키지 폴더에 README.rmd 파일이 하나 생성된다. 그리고 자동으로 .Rbuildignore에 추가가 된다. 필자는 .gitignore 파일에도 README.Rmd를 추가하여 README.Rmd는 깃허브에 연동이 되지 않고, 결과물인 README.md 만 연동이 되도록 설정하였다. 결국, .md 파일 대신에 .Rmd 파일을 이용하므로서 개발자는 함수의 여러 사용법을 rmarkdown 코드를 사용하여 README.md에 넣을 수 있게 되는 것이다. 파일의 내용을 알맞게 수정한 후 README.md파일을 만들고, Git 탭을 통하여 업데이트 시키도록 하자.

패키지 README.Rmd 파일 결과

패키지 README.Rmd 파일 결과

참고 문헌

  1. Wickham, Hadley. R packages: organize, test, document, and share your code. " O’Reilly Media, Inc.“, 2015.

  2. Jennifer (Jenny) Bryan, Write your own R package STAT 545

  3. Writing R extension (https://cran.r-project.org/doc/manuals/r-release/R-exts.html#The-DESCRIPTION-file)


SHARE TO



티스토리 툴바