Search code examples
rnamespacesdevtools

Created package not running functions from imported packages in NAMESPACE file


this is my first package. Here is how my .R file goes, with 3 functions, two of them to be exported. Their actual content doesn't matter much, only that it uses a lot of tidyverse functions.

#' @import tidyverse
#' @importFrom labelled set_variable_labels var_label
#' @importFrom readxl read_excel cell_cols

NULL

#' Carregando dados brutos
#'
#' @param diretorio_dados Diretório onde os microdados originais em formato de texto estão armazenados
#'
#' @param diretorio_dicionario Diretório onde o dicionário da pesquisa em formato xls está armaezenado
#'
#' @param ... vetores com datas das pesquisas de interesse no  formato \code{c('trimestre', 'ano')}
#'
#' @return Lista de dataframes, sendo cada entrada um trimestre/ano em \code{...}
#' @encoding UTF-8
#' @export
#'
#' @examples
#' datazoom_pnadc('./Desktop', './Desktop', c(1, 2000), c(2, 2000))
#'
datazoom_pnadc <- function(diretorio_dados,
                           diretorio_dicionario,
                           ...) {


  return(NULL)
}

 #' Painel básico
 #'
 #' @param build_data Default \code{TRUE}.
 #' Se \code{TRUE}, implementa primeiro \code{\link{datazoom_pnadc}} e depois
 #' monta paineis de indivíduos. Se \code{FALSE}, a função constrói paneis a partir de dados já carregados no R
 #'
 #' @param dados_prontos Bases de dados para diferentes trimestres da PNAD contínua.
 #' Necessário se \code{build_data = FALSE}
 #'
 #' @param local_dados Diretório onde os microdados originais em formato de texto estão armazenados
 #' caso \code{build_data = TRUE}
 #'
 #' @param local_dicionarios Diretório onde o dicionário da pesquisa em formato xls está armaezenado caso
 #' \code{build_data = TRUE}
 #'
 #' @param periodos Lista de vetores com períodos de interesse no formato
 #' \code{periodos = list(c(trimestre1, ano1), c(trimestre2, ano2), ...)}
 #'
 #' @encoding UTF-8
 #'
 #' @return Lista de dataframes, sendo cada entrada um trimestre/ano
 #'
 #' @examples
 #' PNADC_2012 <- datazoom_pnadc(diretorio_dados = './Desktop',
 #' diretorio_dicionario = './pnadcontinua/Desktop',
 #' c(1,2012), c(2,2012))
 #'
 #' teste <- pnadc_painel_basico(build_data = FALSE,
 #'                              dados_prontos = PNADC_2012)
 #'
 #' teste2 <- pnadc_painel_basico(build_data = TRUE,
 #'                               local_dados = './pnadcontinua',
 #'                               local_dicionario = './pnadcontinua/Dicionario_e_input',
 #'                               periodos = list(c(1,2012), c(2,2012)))
 #' @export
pnadc_painel_basico <- function(build_data = TRUE, ...){
    return(NULL)

}

For some reason, even after running devtools::document() and having this in my NAMESPACE file:

# Generated by roxygen2: do not edit by hand

export(datazoom_pnadc)
export(pnadc_painel_basico)
import(tidyverse)
importFrom(labelled,set_variable_labels)
importFrom(labelled,var_label)
importFrom(readxl,cell_cols)
importFrom(readxl,read_excel)

Functions from the package do not run after it is installed and loaded if I do not set library(tidyverse), library(labelled) and library(readxl)beforehand.

Alongside the other required parts, my DESCRIPTION file has this:

Imports: 
    labelled,
    readxl,
    tidyverse

Can someone help?


Solution

  • Moving tidyverse from Imports to Depends in DESCRIPTION would make it work, but is not the recommended approach if you are developing a formal package. Like @Bruno commented:

    > usethis::use_package("tidyverse")
    Error: 'tidyverse' is a meta-package and it is rarely a good idea to
    depend on it. Please determine the specific underlying package(s) that
    offer the function(s) you need and depend on that instead. For data 
    analysis projects that use a package structure but do not implement a
    formal R package, adding 'tidyverse' to Depends is a reasonable 
    compromise. Call `use_package("tidyverse", type = "depends")` to achieve
    this.
    

    The reason why having it in Imports does not work is that only variables exported by the packages listed there are placed on the search path, as mentioned in the section Package namespaces of Writing R Extensions:

    Only the exported variables are placed in the attached frame. Loading a package that imports variables from other packages will cause these other packages to be loaded as well (unless they have already been loaded), but they will not be placed on the search path by these implicit loads. Thus code in the package can only depend on objects in its own namespace and its imports (including the base namespace) being visible

    tidyverse, being a meta-package, does not export the functions of its included packages, but uses the .onAttach hook to attach these packages (see tidyverse:::.onAttach for details). This means that if tidyverse is imported using the above method then this hook will not run and the variables exported by the other packages will not be added to the search path, which is why you can not access them.

    Putting tidyverse under Depends does run the .onAttach hook, and therefore the other packages are also attached.