当代码在库中时,do.call错误“第二个参数必须是S4Vectors的列表”

时间:2016-11-25 14:34:03

标签: r package s4

这是在另一个问题的背景下提出的一个问题: Extract and paste together multiple columns of a data frame like object using a vector of column names

我收到了基于do.call用法的答案,当代码是库的一部分时,该答案似乎不起作用,但在作为主脚本的一部分实现时效果很好。

这是我尝试制作一个简化的例子:

档案example.do.call.R

library(S4Vectors)
library(test.package)
data <- DataFrame(A=letters[1:6], B=LETTERS[1:6])

test_do_paste <- function(data) {
    groups <- c("A", "B")
    combined_letters <- do.call(paste, data[groups])
    print(combined_letters)
}

test_do_paste(data)
#test.package::test_do_paste(data)

我根据https://hilaryparker.com/2014/04/29/writing-an-r-package-from-scratch/组织和安装的软件包中存在相同的test_do_paste函数作为单个函数。

如上所述运行Rscript example.do.call.R时,我获得了预期的结果:

[1] "a A" "b B" "c C" "d D" "e E" "f F"

但是,如果我切换到注释版本(使用库中的函数),我会收到以下错误:

Error in do.call(paste, data[groups]) : second argument must be a list
Calls: <Anonymous> -> do.call
Execution halted

我的问题是:

  1. 为什么?

  2. 如何避免错误?

  3. 一些调查

    我使用普通data.frame代替DataFrame

    在这种情况下,错误不会发生。

    请注意,在我的实际应用程序中,我实际上使用的是比DataFrame更复杂的对象,但是有一个colData函数可以从此对象中提取DataFrame

    如果能够将此问题进一步转换为正常data.frame,也许有办法解决问题。

    as.data.frame实际上是这样做的,所以问题2在我的案例中至少有这个解决方案。

    我在函数

    中插入了print(class(data[groups]))

    在这两种情况下,我都会得到以下结果:

    [1] "DataFrame"
    attr(,"package")
    [1] "S4Vectors"
    

    所以,显然,即使在有效的情况下,我作为do.call的第二个参数提供的对象也不是列表。

    我在函数中插入了print(do.call)

    从库中运行时,我只获得几行:

    function (what, args, quote = FALSE, envir = parent.frame())
    {
        if (!is.list(args)) 
            stop("second argument must be a list")
        if (quote) 
            args <- lapply(args, enquote)
        .Internal(do.call(what, args, envir))
    }
    <bytecode: 0x1b7cdd8>
    <environment: namespace:base>
    

    但是当在脚本中运行时,还有更多的输出:

    function (what, args, quote = FALSE, envir = parent.frame()) 
    standardGeneric("do.call")
    <environment: 0x1d8c568>
    attr(,"generic")
    [1] "do.call"
    attr(,"generic")attr(,"package")
    [1] "BiocGenerics"
    attr(,"package")
    [1] "BiocGenerics"
    attr(,"group")
    list()
    attr(,"valueClass")
    character(0)
    attr(,"signature")
    [1] "what" "args"
    attr(,"default")
    Method Definition (Class "derivedDefaultMethod"):
    
    function (what, args, quote = FALSE, envir = parent.frame()) 
    {
        if (!is.list(args)) 
            stop("second argument must be a list")
        if (quote) 
            args <- lapply(args, enquote)
        .Internal(do.call(what, args, envir))
    }
    <bytecode: 0x1d8e660>
    <environment: namespace:base>
    
    Signatures:
            what 
    target  "ANY"
    defined "ANY"
    attr(,"skeleton")
    (function (what, args, quote = FALSE, envir = parent.frame()) 
    {
        if (!is.list(args)) 
            stop("second argument must be a list")
        if (quote) 
            args <- lapply(args, enquote)
        .Internal(do.call(what, args, envir))
    })(what, args, quote, envir)
    attr(,"class")
    [1] "standardGeneric"
    attr(,"class")attr(,"package")
    [1] "methods"
    

    这提出了更多问题:

    1. 为什么会出现这种差异?

    2. 可以解释“库”案例中的错误吗?

0 个答案:

没有答案