R中的掩蔽方法 [英] Masking methods in R

查看:348
本文介绍了R中的掩蔽方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题,特别是这个答案提出了以下问题:我如何得到关于R中方法掩蔽的警告?

This question and in particular this answer brought up the following question: How can I get a warning about the masking of methods in R?

如果您在干净的R会话中运行以下代码,您会注意到加载 dplyr 更改默认方法滞后

If you run the following code in a clean R session, you'll notice that loading dplyr changes the default method for 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 您会收到几个蒙版对象的警告,但没有关于滞后被隐藏的默认方法的警告。原因是当调用滞后时,调用 stats 包中的通用函数。

If you attach the package dplyr, you get warnigns for several masked objects, but no warning about the default method for lag being masked. The reason is that when calling lag, the generic function from the stats package is called.

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

方法(滞后)只是告诉我有一种方法 lag.default 。我可以看到有两种方法使用 getAnywhere

And methods(lag) just tells me that there is a method lag.default. I can see that there are two methods using 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

但是,这需要我知道,如果 dplyr 更改了默认的滞后方法。有没有办法检查方法是否被掩盖?也许有这样的功能:

But this requires that I know to check if the default lag method was changed by dplyr. Is there any way to check if methods were masked? Perhaps there is a function like this:

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

注意:只有当我加载 dplyr require(dplyr)时发出警告。如果我只是加载命名空间而不附加包,方法也会重载(例如,我调用 dplyr :: mutate ,或者甚至使用另一个函数调用一个 dplyr 使用 importFrom 导入的功能)。

NB: It is not enough to have a warning when I load dplyr with require(dplyr). The method also gets overloaded if I just load the namespace without attaching the package (e.g. I call dplyr::mutate, or even I use a function from another package that calls a dplyr function that was imported using importFrom).

推荐答案

更新现在,在 github ,试图解决这些问题。它仍然远非理想的解决方案,但它在解决问题上有一定的作用。它目前具有 require library warnS3Methods 的功能。

Update There is now an R package on github that tries to solve these issues. It is still far from an ideal solution, but it goes som way towards solving the issue. It currently has functions require, library and 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方法的想法。这绝对不是一个完美的解决方案,但是我猜,直到有人提出了一个更好的想法,它至少将帮助调试。

This is only a an idea of how one can find masked S3 methods. It is by no means a perfect solution, but I guess until somebody comes up with a better idea it will at least help with debuging.

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

从干净的工作区使用上述功能,但没有加载程序包),您可以观察以下内容:

Called from a clean workspace (with the above functions, but no packages loaded), you can then observe the following:

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 方法。实际上并没有告诉你,哪一个是掩盖另一个。它只是指出潜在的问题。

That just tells you that here are two lag.default methods. It does not actually tell you, which one is masking the other. It just points out potential problems.

这篇关于R中的掩蔽方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆