2

当单独应用于向量的每个元素时,我的函数给出的结果与使用 sapply 不同。快把我逼疯了!

我正在使用的项目:这个(简化的)参数列表另一个函数被调用:

f <- as.list(match.call()[-1])
> f
$ampm
c(1, 4)

要复制它,您可以运行以下命令:

foo <- function(ampm) {as.list(match.call()[-1])}
f <- foo(ampm = c(1,4))

这是我的功能。它只是从字符串中删除 'c(...)'。

stripConcat <- function(string) {
    sub(')','',sub('c(','',string,fixed=TRUE),fixed=TRUE)
}

单独应用时,它可以正常工作,这就是我想要的:

> stripConcat(f)
[1] "1, 4"

但是当与 sapply 一起使用时,它会给出完全不同的东西,这是我不想要的:

> sapply(f, stripConcat)
 ampm
[1,] "c" 
[2,] "1" 
[3,] "4" 

Lapply 也不起作用:

> lapply(f, stripConcat)
$ampm
[1] "c" "1" "4"

其他任何应用功能都没有。这让我发疯——我认为 lapply 和 sapply 应该与重复应用到列表或向量的元素相同!

4

1 回答 1

2

我相信,您所看到的差异仅仅是由于 as.character 如何强制列表的元素。

x2 <- list(1:3, quote(c(1, 5)))
as.character(x2)
[1] "1:3"     "c(1, 5)"

lapply(x2, as.character)
[[1]]
[1] "1" "2" "3"

[[2]]
[1] "c" "1" "5"

f不是调用,而是第一个元素是调用的列表。

is(f)
[1] "list"   "vector"
as.character(f)
[1] "c(1, 4)"

> is(f[[1]])
[1] "call"     "language"
> as.character(f[[1]])
[1] "c" "1" "4"

sub试图将任何不是字符的东西强制转换为字符。
当您传递 sub 列表时,它会调用as.character. 当你给它一个调用时,它会调用那个. list
as.charactercall


看起来对于您的stripConcat功能,您更喜欢列表作为输入。

在这种情况下,我会为该功能推荐以下内容:

stripConcat <- function(string) {
    if (!is.list(string))
      string <- list(string)
    sub(')','',sub('c(','',string,fixed=TRUE),fixed=TRUE)
}

但是请注意,该字符串是用词不当,因为您似乎从未打算传递stripConcat字符串。(当然,这不是一个问题)

于 2013-05-20T21:34:33.567 回答