2015-06-04 24 views
16

This question và cụ thể là this answer đưa ra câu hỏi sau: Làm thế nào tôi có thể nhận được cảnh báo về việc che dấu các phương thức trong R?Phương thức sao chép trong R

Nếu bạn chạy mã sau trong phiên R sạch, bạn sẽ nhận thấy rằng việc tải dplyr thay đổi phương thức mặc định cho lag.

lag(1:3, 1) 
## [1] 1 2 3 
## attr(,"tsp") 
## [1] 0 2 1 
require(dplyr) 
lag(1:3, 1) 
## [1] NA 1 2 

Nếu bạn đính kèm các gói dplyr, bạn sẽ có được warnigns cho một số đối tượng bịt mặt, nhưng không có cảnh báo về phương pháp mặc định cho lag được đeo mặt nạ. Lý do là khi gọi lag, chức năng chung từ gói stats được gọi.

lag 
## function (x, ...) 
## UseMethod("lag") 
## <bytecode: 0x000000000c072188> 
## <environment: namespace:stats> 

methods(lag) chỉ cho tôi biết rằng có phương pháp lag.default. Tôi có thể thấy rằng có hai phương pháp sử dụng getAnywhere:

getAnywhere(lag.default) 
## 2 differing objects matching ‘lag.default’ were found 
## in the following places 
## registered S3 method for lag from namespace dplyr 
## namespace:dplyr 
## namespace:stats 
## Use [] to view one of them 

Nhưng điều này đòi hỏi mà tôi biết để kiểm tra xem phương pháp mặc định lag được thay đổi bằng cách dplyr. Có cách nào để kiểm tra xem các phương pháp có bị che khuất không? Có lẽ đó là một chức năng như thế này:

checkMethodMasking(dplyr) 
## The following methods are masked from 'package:dplyr': 
## lag.default 

NB: Nó không phải là đủ để có được một cảnh báo khi tôi tải dplyr với require(dplyr). Phương pháp này cũng bị quá tải nếu tôi chỉ tải không gian tên mà không đính kèm gói (ví dụ: tôi gọi dplyr::mutate hoặc thậm chí tôi sử dụng chức năng từ gói khác gọi là dplyr chức năng được nhập bằng cách sử dụng importFrom).

+0

FWIW dplyr không ghi đè lên phương thức đó trong phiên bản tiếp theo – hadley

Trả lời

8

Cập nhật Hiện có gói R trên github cố gắng giải quyết những vấn đề này. Nó vẫn còn xa so với một giải pháp lý tưởng, nhưng nó đi một cách nào đó để giải quyết vấn đề. Nó hiện có chức năng require, librarywarnS3Methods.

devtools::install_github("blasern/warnS3") 
require(warnS3) 

# Examples 
require2(dplyr) 
## Loading required package: dplyr 
## 
## Attaching package: ‘dplyr’ 
## 
## The following object is masked from ‘package:stats’: 
## 
## filter 
## 
## The following objects are masked from ‘package:base’: 
## 
## intersect, setdiff, setequal, union 
## 
## The following methods are masked by 'package:dplyr': 
## 
## 'lag.default' from 'package:stats' 

require2(roxygen2) 
## Loading required package: roxygen2 
## The following methods are masked by 'package:roxygen2': 
## 
## 'escape.character' from 'package:dplyr' 

warnS3Methods() 
## The following methods are available in multiple packages: 
## 
## 'escape.character' in packages: dplyr, roxygen2 
## 'lag.default' in packages: dplyr, stats 

Đây chỉ là ý tưởng về cách người ta có thể tìm thấy các phương pháp mặt nạ S3. Nó không phải là một giải pháp hoàn hảo, nhưng tôi đoán cho đến khi có ai đó đưa ra một ý tưởng tốt hơn, ít nhất nó sẽ giúp gỡ lỗi.

#' Get all S3 methods from a package 
#' 
#' Find all S3 methods from a package 
#' 
#' @param pkg can be either the name of an installed package 
#' or the path of a package 
getPkgS3Methods <- function(pkg){ 
    if (basename(pkg) == pkg) pkg <- path.package(pkg) 
    ns <- parseNamespaceFile(basename(pkg), 
          dirname(pkg), 
          mustExist = FALSE) 
    if (length(ns$S3methods) == 0) return(NULL) 
    df <- cbind.data.frame(basename(pkg), ns$S3methods) 
    colnames(df) <- c("package", "method", "class", "other") 
    df 
} 

#' Get masked S3 methods 
#' 
#' Finds all S3 methods that are currently available that are 
#' duplicated 
getMaskedS3Methods <- function(){ 
    paths <- as.character(gtools::loadedPackages(silent = TRUE)[, "Path"]) 
    lst <- lapply(paths, getPkgS3Methods) 
    all_methods <- do.call(rbind, lst) 
    duplicates <- 
    duplicated(all_methods[, c("method", "class")]) | 
    duplicated(all_methods[, c("method", "class")], fromLast = TRUE) 
    res <- all_methods[duplicates, ] 
    res[order(res$method, res$class, res$package), ] 
} 

gọi từ một không gian làm việc sạch (với các chức năng trên, nhưng không có gói nạp), sau đó bạn có thể quan sát như sau:

getMaskedS3Methods() 
## [1] package method class other 
## <0 rows> (or 0-length row.names) 

require(dplyr) 
getMaskedS3Methods() 
## package method class other 
## 143 dplyr lag default <NA> 
## 438 stats lag default <NA> 

Đó chỉ nói với bạn rằng đây là hai lag.default phương pháp. Nó không thực sự cho bạn biết, cái nào đang che giấu cái kia. Nó chỉ ra những vấn đề tiềm ẩn.

+0

Tôi thực sự không hiểu tại sao mớ hỗn độn này được tạo ra, rất nhiều vấn đề do kết hợp các tên đối tượng xung đột với tác giả của gói «dplyr' (rất tốt otrherwise) – Qbik

Các vấn đề liên quan