这是在另一个问题的背景下提出的一个问题: 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
我的问题是:
为什么?
如何避免错误?
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"
这提出了更多问题:
为什么会出现这种差异?
可以解释“库”案例中的错误吗?