#R – Deprecate functions with roxygen2

[This article was first published on Mirai Solutions, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

We show how to use roxygen2 tags and templates for deprecating existing documented functions.

Introduction

Package roxygen2 provides a powerful way of documenting packages and objects inside them. In particular, great flexibility is available for organizing the documentation content in source files and templates, and render it as desired in the corresponding help pages.

We can leverage on this flexibility to adapt an existing package documentation upon making a function deprecated (and similarly defunct). As stated in the base-R ‘Marking Objects as Deprecated’ documentation (help(Deprecated)):

The original help page for these functions is often available at help(“oldName-deprecated”) (note the quotes). Functions should be listed in help(“pkg-deprecated”) for an appropriate pkg, including base.

Deprecate existing functions

We show how an existing and documented function myFun in package ourPkg can be deprecated, and the documentation adjusted accordingly by re-arranging the roxygen2 documentation content.

<span class="c1">## myFun.r</span><span class="w">
</span><span class="cd">#' @title My function.</span><span class="w">
</span><span class="cd">#' @description My function.</span><span class="w">
</span><span class="cd">#' @param arg1 My first argument.</span><span class="w">
</span><span class="cd">#' @param arg2 My second argument.</span><span class="w">
</span><span class="cd">#' @return My return value.</span><span class="w">
</span><span class="cd">#' @export</span><span class="w">
</span><span class="n">myFun</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">arg1</span><span class="p">,</span><span class="w"> </span><span class="n">arg2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="s2">"My return value"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span>

Let us assume a new function myNewFunction exists as a replacement for the old myFun, which becomes deprecated. We want to achieve the following

  • list myFun in help("ourPkg-deprecated""), along with its replacement;
  • make its original documentation available via help("myFun-deprecated").

This can be obtained by

  • creating generic content for help("ourPkg-deprecated"");
  • adjusting the existing myFun documentation content.
Package-level documentation

Generic content for help("ourPkg-deprecated") is defined in its own source file:

<span class="c1">## ourPkg-deprecated.r</span><span class="w">
</span><span class="cd">#' @title Deprecated functions in package \pkg{ourPkg}.</span><span class="w">
</span><span class="cd">#' @description The functions listed below are deprecated and will be defunct in</span><span class="w">
</span><span class="cd">#'   the near future. When possible, alternative functions with similar</span><span class="w">
</span><span class="cd">#'   functionality are also mentioned. Help pages for deprecated functions are</span><span class="w">
</span><span class="cd">#'   available at \code{help("<function>-deprecated")}.</span><span class="w">
</span><span class="cd">#' @name ourPkg-deprecated</span><span class="w">
</span><span class="cd">#' @keywords internal</span><span class="w">
</span><span class="kc">NULL</span><span class="w">
</span>
Function-specific documentation

Function-specific content is added to the ourPkg-deprecated help page from the corresponding source file, where we also want to make the original help page available via help("myFun-deprecated").

The source file of myFun is then modified as follows:

<span class="c1">## myFun.r</span><span class="w">
</span><span class="cd">#' @title My function.</span><span class="w">
</span><span class="cd">#' @description My function.</span><span class="w">
</span><span class="cd">#' @param arg1 My first argument.</span><span class="w">
</span><span class="cd">#' @param arg2 My second argument.</span><span class="w">
</span><span class="cd">#' @return My return value.</span><span class="w">
</span><span class="cd">#'</span><span class="w">
</span><span class="cd">#' @name myFun-deprecated</span><span class="w">
</span><span class="cd">#' @usage myFun(arg1, arg2)</span><span class="w">
</span><span class="cd">#' @seealso \code{\link{ourPkg-deprecated}}</span><span class="w">
</span><span class="cd">#' @keywords internal</span><span class="w">
</span><span class="kc">NULL</span><span class="w">

</span><span class="cd">#' @rdname ourPkg-deprecated</span><span class="w">
</span><span class="cd">#' @section \code{myFun}:</span><span class="w">
</span><span class="cd">#' For \code{myFun}, use \code{\link{myNewFun}}.</span><span class="w">
</span><span class="cd">#'</span><span class="w">
</span><span class="cd">#' @export</span><span class="w">
</span><span class="n">myFun</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">arg1</span><span class="p">,</span><span class="w"> </span><span class="n">arg2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">.Deprecated</span><span class="p">(</span><span class="s2">"myNewFun"</span><span class="p">)</span><span class="w">
  </span><span class="s2">"My return value"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span>

Two blocks of roxygen2 tags have been added to the existing documentation content.

  • The first block is used to create the myFun-deprecated help page, detached from the myFun object. For this reason we need to explicitly add the original function signature as ‘Usage’ section. We also add a ‘See Also’ link to ourPkg-deprecated.
  • The second block adds myFun-specific content to the ourPkg-deprecated help page. The standard ‘Usage’ section is added automatically, and we create a function-specific section where using myNewFun is suggested. Such content will be collected and shown in help("ourPkg-deprecated") for all deprecated functions with similar tags structure.

Note also that help(myFun) will point to the ourPkg-deprecated help page, and that @keywords internal prevents the corresponding topics from appearing in the package documentation index.

Using roxygen2 templates

Deprecating functions as described above can be automated using templates. One can define a template for each additional block.

<span class="c1">## template-depr_pkg.r</span><span class="w">
</span><span class="cd">#' @name ourPkg-deprecated</span><span class="w">
</span><span class="cd">#' @section \code{<%= old %>}:</span><span class="w">
</span><span class="cd">#' For \code{<%= old %>}, use \code{\link{<%= new %>}}.</span><span class="w">
</span>
<span class="c1">## template-depr_fun.r</span><span class="w">
</span><span class="cd">#' @name <%= fun %>-deprecated</span><span class="w">
</span><span class="cd">#' @usage <%= gsub("\n", "\n#' ", roxygen2:::wrapString(roxygen2:::function_usage(fun, formals(fun)))) %></span><span class="w">
</span><span class="cd">#' @seealso \code{\link{ourPkg-deprecated}}</span><span class="w">
</span><span class="cd">#' @keywords internal</span><span class="w">
</span>

Note the presence of template variables and of some roxygen2 internals for automating the construction of the ‘Usage’ section (handling multiple lines in case of many arguments).

Deprecating herFun in favor of herNewFun then results in the simple inclusion of the templates in the function source.

<span class="c1">## herFun.r</span><span class="w">
</span><span class="cd">#' @title Her function.</span><span class="w">
</span><span class="cd">#' @description Her function.</span><span class="w">
</span><span class="cd">#' @param arg1 Her first argument.</span><span class="w">
</span><span class="cd">#' @param arg2 Her second argument.</span><span class="w">
</span><span class="cd">#' @return Her return value.</span><span class="w">
</span><span class="cd">#'</span><span class="w">
</span><span class="cd">#' @templateVar fun herFun</span><span class="w">
</span><span class="cd">#' @template template-depr_fun</span><span class="w">
</span><span class="kc">NULL</span><span class="w">

</span><span class="cd">#' @templateVar old herFun</span><span class="w">
</span><span class="cd">#' @templateVar new herNewFun</span><span class="w">
</span><span class="cd">#' @template template-depr_pkg</span><span class="w">
</span><span class="cd">#'</span><span class="w">
</span><span class="cd">#' @export</span><span class="w">
</span><span class="n">herFun</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">arg1</span><span class="p">,</span><span class="w"> </span><span class="n">arg2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">.Deprecated</span><span class="p">(</span><span class="s2">"herNewFun"</span><span class="p">)</span><span class="w">
  </span><span class="s2">"Her return value"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span>

Example package manual and sources

A complete example of ourPkg is
avalailable for download.
The package contains functions myFun, yourFun, herFun, hisFun, where all but yourFun are deprecated in favor of *NewFun, using roxygen2 templates for herFun and hisFun.

The resulting documentation content can be assessed in the corresponding PDF reference manual.

To leave a comment for the author, please follow the link and comment on their blog: Mirai Solutions.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)