2015-06-04 3 views
16

This question и, в частности this answer, возникли следующие вопросы: Как я могу получить предупреждение о маскировке методов в R?Методы маскирования в R

Если вы выполните следующий код в чистом сеансе R, вы заметите, что загрузка dplyr изменяет метод по умолчанию для 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 

Если вы приложите пакет dplyr, вы получите warnigns несколько замаскированных объектов, но никакого предупреждения о методе по умолчанию lag не маскируется. Причина в том, что при вызове lag вызывается общая функция из пакета stats.

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

И methods(lag) просто говорит мне, что есть метод lag.default. Я могу видеть, что есть два метода с использованием 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 

Но это требует, чтобы я знаю, чтобы проверить, если метод по умолчанию lag был изменен dplyr. Есть ли способ проверить, маскированы ли методы? Может быть, есть функция, как это:

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

NB: Это не достаточно, чтобы иметь предупреждение, когда я загружаю dplyr с require(dplyr). Метод также перегружается, если я просто загружаю пространство имен без привязки пакета (например, я вызываю dplyr::mutate или даже пользуюсь функцией из другого пакета, который вызывает функцию dplyr, которая была импортирована с использованием importFrom).

+0

FWIW dplyr не переопределяет этот метод в следующей версии – hadley

ответ

8

Обновление В настоящее время существует пакет R на github, который пытается решить эти проблемы. Это еще далеко не идеальное решение, но оно идет в сторону решения проблемы. В настоящее время он имеет функции require, library и warnS3Methods.

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 

Это всего лишь идея о том, как можно найти маскированные методы S3. Это ни в коем случае не идеальное решение, но я думаю, пока кто-нибудь придумает лучшую идею, это, по крайней мере, поможет в отладке.

#' 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), ] 
} 

Вызывается из чистого рабочего пространства (с вышеперечисленными функциями, но никакие пакеты не загружены), вы можете наблюдать следующее:

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> 

Это просто говорит вам, что здесь два lag.default методы. На самом деле это не говорит вам, какой из них маскирует другой. Это просто указывает на потенциальные проблемы.

+0

Я действительно не понимаю, почему этот беспорядок был создан, так много проблем из-за включения имен конфликтующих объектов по автору (очень хороший противный) пакет 'dplyr' – Qbik

Смежные вопросы