paste() turns list element character vector into deparsed expression. Why?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

paste() turns list element character vector into deparsed expression. Why?

Boris Steipe
I was just surprised by very un-intuitive behaviour of paste(), which appears to collapse a one-column data frame or one-element list into a deparsed expression, rather than producing the expected string. Can someone kindly explain what's going on here?


reprex:
=======

list(s = c("xyz", "uvw"))
#     s
# 1 xyz
# 2 uvw

paste(list(s = c("xyz", "uvw")), collapse = "")
# [1] "c(\"xyz\", \"uvw\")"   # This is unexpected!

I would have expected:
# [1] "xyzuvw"
 
... which I do get with e.g.
paste(list(s = c("xyz", "uvw"))$s, collapse = "")

But what logic is there in returning a deparsed expression?



Thanks!
Boris
______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: paste() turns list element character vector into deparsed expression. Why?

Ege Rubak
I think `paste()` just calls `as.character()` on each input argument
and then collapses things afterwards. Calling `as.character()` on the
first input argument generates exactly the output you show (and didn't
expect) and there is nothing to collapse. So changing `collapse = ""`
to anything else doesn't change behaviour.

The question is reduced to how `as.character()` should handle a list as
input. It seems to me that this input is so generic that it is hard to
handle graciously without all kinds of special cases. So you expect the
length one list

as.character(list(s = c("xyz", "uvw"))

to return the length 2 character vector `c("xyz", "uvw")`? What should

as.character(list(s = c("xyz", "uvw"), t = c("a", "b", "c"))

return?

Kind regards,
Ege

On Mon, 2020-11-09 at 11:38 +0000, Boris Steipe wrote:

> I was just surprised by very un-intuitive behaviour of paste(), which
> appears to collapse a one-column data frame or one-element list into
> a deparsed expression, rather than producing the expected string. Can
> someone kindly explain what's going on here?
>
>
> reprex:
> =======
>
> list(s = c("xyz", "uvw"))
> #     s
> # 1 xyz
> # 2 uvw
>
> paste(list(s = c("xyz", "uvw")), collapse = "")
> # [1] "c(\"xyz\", \"uvw\")"   # This is unexpected!
>
> I would have expected:
> # [1] "xyzuvw"
>  
> ... which I do get with e.g.
> paste(list(s = c("xyz", "uvw"))$s, collapse = "")
>
> But what logic is there in returning a deparsed expression?
>
>
>
> Thanks!
> Boris
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: paste() turns list element character vector into deparsed expression. Why?

Boris Steipe
Thanks Ege -

That narrows it down, ... but it's still weird.

My issue is that I don't consider "c(\"xyz\", \"uvw\")" to be a valid character representation of a list. c() is a function, so "c(\"xyz\", \"uvw\")" is a string representation of a function call that could be  eval(parse(...))'ed into a two-element vector ... but considering this a coercion seems really weird.

What do I think your example should return? An object of the same general structure as the input, with non-character components coerced to character. And if that's not possible because there is no good character representation (e.g. if its a closure) than it should return an error.


Cheers,
Boris

 


> On 2020-11-09, at 22:24, Ege Rubak <[hidden email]> wrote:
>
> EXTERNAL EMAIL:  Treat content with extra caution.
>
> I think `paste()` just calls `as.character()` on each input argument
> and then collapses things afterwards. Calling `as.character()` on the
> first input argument generates exactly the output you show (and didn't
> expect) and there is nothing to collapse. So changing `collapse = ""`
> to anything else doesn't change behaviour.
>
> The question is reduced to how `as.character()` should handle a list as
> input. It seems to me that this input is so generic that it is hard to
> handle graciously without all kinds of special cases. So you expect the
> length one list
>
> as.character(list(s = c("xyz", "uvw"))
>
> to return the length 2 character vector `c("xyz", "uvw")`? What should
>
> as.character(list(s = c("xyz", "uvw"), t = c("a", "b", "c"))
>
> return?
>
> Kind regards,
> Ege
>
> On Mon, 2020-11-09 at 11:38 +0000, Boris Steipe wrote:
>> I was just surprised by very un-intuitive behaviour of paste(), which
>> appears to collapse a one-column data frame or one-element list into
>> a deparsed expression, rather than producing the expected string. Can
>> someone kindly explain what's going on here?
>>
>>
>> reprex:
>> =======
>>
>> list(s = c("xyz", "uvw"))
>> #     s
>> # 1 xyz
>> # 2 uvw
>>
>> paste(list(s = c("xyz", "uvw")), collapse = "")
>> # [1] "c(\"xyz\", \"uvw\")"   # This is unexpected!
>>
>> I would have expected:
>> # [1] "xyzuvw"
>>
>> ... which I do get with e.g.
>> paste(list(s = c("xyz", "uvw"))$s, collapse = "")
>>
>> But what logic is there in returning a deparsed expression?
>>
>>
>>
>> Thanks!
>> Boris
>> ______________________________________________
>> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide
>> http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: paste() turns list element character vector into deparsed expression. Why?

Ege Rubak
I agree that it is weird, but I don't see that it is easy to coerce a
list to character of the same structure. In my example (missing the
trailing parenthesis, sorry...) the input is a length two list and the
output is a length two character vector, so in the general case the
rationale seems to be that the output should have the same length as
the input, which makes sense. What specific length two character vector
would you suggest for this example? Would you paste the elements
together with an arbitrary separator of your choice?

In the more general case these elements could be anything: numbers,
characters, functions or even new lists, and I agree that it most often
probably just would make most sense to return an error. Actually I
think it is a bad idea to call `as.character()` on a list in the first
place. Logically this doesn't make much sense. If you want to use
`as.charater()` on each element in the list you should use `lapply()`.

If you really insist on representing a complicated structure as a list
as character I don't see any better general way to represent the list
as character than what R currently does.

Kind regards,
Ege


On Mon, 2020-11-09 at 12:58 +0000, Boris Steipe wrote:

> Thanks Ege -
>
> That narrows it down, ... but it's still weird.
>
> My issue is that I don't consider "c(\"xyz\", \"uvw\")" to be a valid
> character representation of a list. c() is a function, so "c(\"xyz\",
> \"uvw\")" is a string representation of a function call that could
> be  eval(parse(...))'ed into a two-element vector ... but considering
> this a coercion seems really weird.
>
> What do I think your example should return? An object of the same
> general structure as the input, with non-character components coerced
> to character. And if that's not possible because there is no good
> character representation (e.g. if its a closure) than it should
> return an error.
>
>
> Cheers,
> Boris
>
>  
>
>
> > On 2020-11-09, at 22:24, Ege Rubak <[hidden email]> wrote:
> >
> > EXTERNAL EMAIL:  Treat content with extra caution.
> >
> > I think `paste()` just calls `as.character()` on each input
> > argument
> > and then collapses things afterwards. Calling `as.character()` on
> > the
> > first input argument generates exactly the output you show (and
> > didn't
> > expect) and there is nothing to collapse. So changing `collapse =
> > ""`
> > to anything else doesn't change behaviour.
> >
> > The question is reduced to how `as.character()` should handle a
> > list as
> > input. It seems to me that this input is so generic that it is hard
> > to
> > handle graciously without all kinds of special cases. So you expect
> > the
> > length one list
> >
> > as.character(list(s = c("xyz", "uvw"))
> >
> > to return the length 2 character vector `c("xyz", "uvw")`? What
> > should
> >
> > as.character(list(s = c("xyz", "uvw"), t = c("a", "b", "c"))
> >
> > return?
> >
> > Kind regards,
> > Ege
> >
> > On Mon, 2020-11-09 at 11:38 +0000, Boris Steipe wrote:
> > > I was just surprised by very un-intuitive behaviour of paste(),
> > > which
> > > appears to collapse a one-column data frame or one-element list
> > > into
> > > a deparsed expression, rather than producing the expected string.
> > > Can
> > > someone kindly explain what's going on here?
> > >
> > >
> > > reprex:
> > > =======
> > >
> > > list(s = c("xyz", "uvw"))
> > > #     s
> > > # 1 xyz
> > > # 2 uvw
> > >
> > > paste(list(s = c("xyz", "uvw")), collapse = "")
> > > # [1] "c(\"xyz\", \"uvw\")"   # This is unexpected!
> > >
> > > I would have expected:
> > > # [1] "xyzuvw"
> > >
> > > ... which I do get with e.g.
> > > paste(list(s = c("xyz", "uvw"))$s, collapse = "")
> > >
> > > But what logic is there in returning a deparsed expression?
> > >
> > >
> > >
> > > Thanks!
> > > Boris
> > > ______________________________________________
> > > [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> > > https://stat.ethz.ch/mailman/listinfo/r-help
> > > PLEASE do read the posting guide
> > > http://www.R-project.org/posting-guide.html
> > > and provide commented, minimal, self-contained, reproducible
> > > code.
______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.