Подтвердить что ты не робот

Помощь метода S3 (roxygen2)

Я пытаюсь использовать S3-метод в пакете и думал, что понял, как настроить его, задав здесь вопрос: Предупреждение о непротиворечивости метода S3 при создании пакета R с Roxygen

Но теперь я получаю результаты, которых я не ожидаю. Если я запускаю код ниже непосредственно в R, он дает мне ожидаемые результаты, но если я скомпилирую его в пакет, я не получу правильные результаты (обратите внимание на слово, которое подсчитывается дважды, когда оно должно принимать только уникальные слова из vector a). Я не уверен, что я неправильно настроил.

Файл .R:

#' Find Common Words Between Groups
#' 
#' Find common words between grouping variables (e.g. people).
#' 
#' @param word.list A list of names chacter vectors.
#' @param overlap Minimum/exact amount of overlap.
#' @param equal.or A character vector of c(\code{"equal"}, \code{"greater"}, 
#' \code{"more"}, \code{"less"}).
#' @param \dots In liu of word.list the user may input n number of character 
#' vectors.
#' @rdname common
#' @return Returns a dataframe of all words that match the criteria set by 
#' \code{overlap} and \code{equal.or}.
#' @export
#' @examples
#' \dontrun{
#' a <- c("a", "cat", "dog", "the", "the")                                                              
#' b <- c("corn", "a", "chicken", "the")                                                                
#' d <- c("house", "feed", "a", "the", "chicken")                                                       
#' common(a, b, d, overlap=2)  
#' common(a, b, d, overlap=3)                                                                          
#'                                                                                                      
#' r <- list(a, b, d)  
#' common(r)                                                                                 
#' common(r, overlap=2)                                                                                            
#'                                                                                                     
#' common(word_list(DATA$state, DATA$person)$cwl, overlap = 2) 
#' } 
common <-
function(word.list, ...){
    UseMethod("common")
}

#' @return \code{NULL}
#'
#' @rdname common
#' @method common list
common.list <-
function(word.list, overlap = "all", equal.or = "more", ...){
    if(overlap=="all") {
        OL <- length(word.list) 
    } else {
        OL <- overlap
    }
    LIS <- sapply(word.list, unique)
    DF <- as.data.frame(table(unlist(LIS)), stringsAsFactors = FALSE)
    names(DF) <- c("word", "freq")
    DF <- DF[order(-DF$freq, DF$word), ]
    DF <- switch(equal.or,
        equal = DF[DF$freq == OL, ],
        greater = DF[DF$freq > (OL - 1), ],
        more = DF[DF$freq > (OL - 1), ],
        less = DF[DF$freq < (OL + 1), ])
    rownames(DF) <- 1:nrow(DF)
    return(DF)
}

#' @return \code{NULL}
#'
#' @rdname common
#' @method common default
#' @S3method common default  
common.default <-
    function(..., overlap = "all", equal.or = "more", word.list){
        LIS <- list(...)
        return(common.list(LIS, overlap, equal.or))
}


a <- c("a", "cat", "dog", "the", "the")                                                              
b <- c("corn", "a", "chicken", "the")                                                                
d <- c("house", "feed", "a", "the", "chicken")                                                       
common(a, b, d, overlap=2)  


r <- list(a, b, d)                                                                                   
common(r, overlap=2)                                                                                            

Запуск кода из командной строки (ожидаемое поведение):

> common(a, b, d, overlap=2)  
     word freq
1       a    3
2     the    3
3 chicken    2
>                                                                           
>                                                                                                      
> r <- list(a, b, d)                                                                                   
> common(r, overlap=2)                                                                                            
     word freq
1       a    3
2     the    3
3 chicken    2

Результат после компиляции пакета:

> a <- c("a", "cat", "dog", "the", "the")                                                              
> b <- c("corn", "a", "chicken", "the")                                                                
> d <- c("house", "feed", "a", "the", "chicken")                                                       
> common(a, b, d, overlap=2)  
     word freq
1       a    3
2     the    3
3 chicken    2
>                                                                           
>                                                                                                      
> r <- list(a, b, d)                                                                                   
> common(r, overlap=2)                                                                                            
     word freq
1     the    4
2       a    3
3 chicken    2
4b9b3361

Ответ 1

Ошибка, которую вы видите, чаще всего вызвана тем, что метод списка общего родословного не экспортируется, поэтому вместо него вызывается common.default. Вы можете решить эту проблему, используя devtools::missing_s3 - функция немного эвристична, поэтому вы можете получить несколько ложных срабатываний (например, в настоящее время она не может сказать, что is.list не является методом). Это невероятно распространенная проблема (она меня так много раз поймала), и следующая итерация roxygen сделает больше, чтобы предотвратить ее.

В настоящее время, чтобы правильно экспортировать методы S3 с помощью roxygen, вам необходимо выполнить следующие действия:

  • @S3method generic class (и ничего больше), если вы не хотите документировать метод
  • @method generic class и @export, если вы хотите экспортировать и документировать его.

У вас никогда не должно быть @S3method и @method в том же блоке документации.

Обновление для roxygen2 > 3.0.0

Теперь roxygen автоматически определяет, является ли функция S3-методом так:

  • Никогда не используйте @S3method или @method
  • Используйте @export, если вы хотите, чтобы метод был экспортирован (что вы обычно делаете, даже если общий не является)