Re: [Rd] single assignment affecting multiple sub-structures (PR#7924)

From: Tony Plate <tplate_at_blackmesacapital.com>
Date: Sat 11 Jun 2005 - 13:18:53 GMT

Yes, actually, I have had code using do.call() that returns the result I want working for years. However, I've been trying to reduce the memory usage of my code, and I discovered that in S-PLUS, do.call() appears to make a extra copy of its arguments. When the arguments are very large, this can be important. I found that by constructing a call like the one below, and eval()ing it, S-PLUS would not make unnecessary copies of the arguments.

However, when I tried the same code in R, I found the bug that I described below.

Douglas Bates wrote:

> I hesitate to make such as simplistic suggestion but have you
> considered using do.call to generate the call?
> 
> On 6/9/05, tplate@blackmesacapital.com <tplate@blackmesacapital.com> wrote:
> 

>>I'm trying to create a language structure that is a call to a function
>>with a number of arguments that is only known at run time. I do this by
>>using repeated indices to expand out a call with a single argument.
>>However, when I change one of the arguments, all are changed.
>>
>>I don't see the same behavior when I initially create a call with
>>multiple arguments.
>>
>>Even more strangely, calling identical(call1, call2) before any attempts
>>to modify the structures changes the subsequent behavior to be correct.
>>
>>[If there are better methods to create and modify calls, please let me
>>know!]
>>
>> > # Example of commands that give incorrect results
>> > call1 <- Quote(f(arg[[1]], arg[[1]], arg[[1]]))
>> > call2 <- Quote(f(arg[[1]]))[c(1,2,2,2)]
>> > call1
>>f(arg[[1]], arg[[1]], arg[[1]])
>> > call2
>>f(arg[[1]], arg[[1]], arg[[1]])
>> > call1[[3]][[3]] <- 2
>> > call2[[3]][[3]] <- 2
>> > call1
>>f(arg[[1]], arg[[2]], arg[[1]])
>> > # note that all the arguments of call2 have changed!
>> > call2
>>f(arg[[2]], arg[[2]], arg[[2]])
>> > identical(call1, call2)
>>[1] FALSE
>> >
>> > # if we do 'identical(call1, call2)' directly
>> > # after creation, then everything behaves correctly !??
>> > call1 <- Quote(f(arg[[1]], arg[[1]], arg[[1]]))
>> > call2 <- Quote(f(arg[[1]]))[c(1,2,2,2)]
>> > identical(call1, call2)
>>[1] TRUE
>> > call1
>>f(arg[[1]], arg[[1]], arg[[1]])
>> > call2
>>f(arg[[1]], arg[[1]], arg[[1]])
>> > call1[[3]][[3]] <- 2
>> > call2[[3]][[3]] <- 2
>> > call1
>>f(arg[[1]], arg[[2]], arg[[1]])
>> > call2
>>f(arg[[1]], arg[[2]], arg[[1]])
>> > identical(call1, call2)
>>[1] TRUE
>> >
>> > # The same thing happens when the call is created using 'call()'
>> > call3 <- call("f", call("[[", as.name("arg"), 1))[c(1,2,2,2)]
>> > call3
>>f(arg[[1]], arg[[1]], arg[[1]])
>> > call3[[3]][[3]] <- 2
>> > call3
>>f(arg[[2]], arg[[2]], arg[[2]])
>> >
>> > version
>> _
>>platform i386-pc-mingw32
>>arch i386
>>os mingw32
>>system i386, mingw32
>>status
>>major 2
>>minor 1.0
>>year 2005
>>month 04
>>day 18
>>language R
>> >
>>
>>
>>I also see the same behavior in the development release of R:
>> > version
>> _
>>platform i386-pc-mingw32
>>arch i386
>>os mingw32
>>system i386, mingw32
>>status Under development (unstable)
>>major 2
>>minor 2.0
>>year 2005
>>month 06
>>day 07
>>svn rev 34588
>>language R
>> >
>>
>>-- Tony Plate
>>
>>______________________________________________
>>R-devel@stat.math.ethz.ch mailing list
>>https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>
>

R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Sat Jun 11 23:22:19 2005

This archive was generated by hypermail 2.1.8 : Mon 24 Oct 2005 - 22:27:17 GMT