与功能的个别应用不同

时间:2013-05-20 20:47:39

标签: r sapply

当单独应用于向量的每个元素时,我的函数给出的结果与使用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应该与列表或向量元素的重复应用相同!

1 个答案:

答案 0 :(得分: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试图强迫任何不是角色的人 当您传递子列表时,它会在as.character上调用list 当您通过呼叫时,它会在as.character上呼叫call


对于您的stripConcat功能,您会首选列表作为输入。

在这种情况下,我建议使用以下功能:

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

但请注意, string 是用词不当,因为您似乎没有计划传递stripConcat字符串。 (当然不是这个问题)