Pergunta

When applied individually to each element of the vector, my function gives a different result than using sapply. It's driving me nuts!

Item I'm using: this (simplified) list of arguments another function was called with:

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

To replicate this you can run the following:

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

Here is my function. It just strips the 'c(...)' from a string.

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

When applied alone it works as so, which is what I want:

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

But when used with sapply, it gives something totally different, which I do NOT want:

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

Lapply doesn't work either:

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

And neither do any of the other apply functions. This is driving me nuts--I thought lapply and sapply were supposed to be identical to repeated applications to the elements of the list or vector!

Foi útil?

Solução

The discrepency you are seeing, I believe, is simply due to how as.character coerces elements of a list.

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 not a call, but a list whose first element is a call.

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 attempts to coerce anything that is not a character into a chracter.
When you pass sub a list, it calls as.character on the list.
When you pass it a call, it calls as.character on that call.


It looks like for your stripConcat function, you would prefer a list as input.

In that case, I would recommend the following for that function:

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

Note, however, that string is a misnomer, since it doesn't appear that you are ever planning to pass stripConcat a string. (not that this is an issue, of course)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top