10

パッケージでS3メソッドを使用しようとしていますが、ここで質問した後、セットアップ方法を理解したと思いました。Roxygenを使用してRパッケージをビルドするときのS3メソッドの整合性の警告

しかし、今では予期しない結果が得られます。以下のコードをRで直接実行すると、期待どおりの結果が得られますが、パッケージにコンパイルすると、正しい結果が得られません(から一意の単語のみを取得する必要がある場合に、単語が2回カウントされることに注意してください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
4

1 に答える 1

16

表示されているバグは、一般的なジェネリックのlistメソッドがエクスポートされていないために発生している可能性が高いため、common.default代わりに呼び出されます。この問題は、次を使用して解決できます。このdevtools::missing_s3関数は少しヒューリスティックであるため、誤検知がいくつか発生する可能性があります(たとえば、現在、それis.listがメソッドではないことはわかりません)。これは非常に一般的な問題であり(何度も私を捕らえています)、roxygenの次の反復はそれを防ぐためにより多くのことを行います。

現在、roxygenを使用してS3メソッドを正しくエクスポートするには、次のいずれかを実行する必要があります。

  • @S3method generic class(そして他には何も)メソッドを文書化したくない場合
  • @method generic class@exportエクスポートして文書化する場合。

同じドキュメントブロックにあるべきでは@S3methodありません。@method

roxygen2>3.0.0の更新

これで、roxygenは、関数がS3メソッドであるかどうかを自動的に判断します。

  • 絶対に使用しないで@S3methodください@method
  • メソッドをエクスポートする場合に使用@exportします(ジェネリックがエクスポートされていない場合でも、通常はエクスポートします)。
于 2013-01-16T20:45:46.440 に答える