# Matlab-style multiple assignment in R

**Struggling Through Problems » R**, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)

Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

R again!

You know how in Matlab you can do?

S, I = sort(M)

I like that.

R generic functions makes this possible. First, let’s genericize assignment. I feel like regular “=” and “<-” oughta stay nongeneric, so let’s make a new one.

'%=%' = function(l, r, ...) UseMethod('%=%')

Now the next step is a bit tricky. We need to group several variables on the left of %=%

... a, b, ... %=% foo()

The trick is they have to stay unevaluated. Luckily R uses (what IIRC is called) “pass by name”, so we can do this. Let’s start with a function to take a, b, …

l = function(...) { }

The hard part is grabbing the ‘…’ without evaluating it.

> substitute(...) ...

won’t work, nor will alist(…). I have NO IDEA why, but the following expression (stolen from data.frame()) works:

as.list(substitute(list(...)))[-1L]

So now we have our function

l = function(...) { List = as.list(substitute(list(...)))[-1L] class(List) = 'lbunch' List }

And we can add a specific implementation for our generic %=%:

'%=%.lbunch' = function(l, r, ...) { Names = lapply(l, as.character) Envir = as.environment(-1) for (II in 1:length(Names)) { Name = Names[[II]] assign(Name, r[[II]], pos=Envir) } }

Which just treats the objects “a”, “b” … as strings, and assigns into the caller’s environment.

That’s what I had first, but it can be made better. With the above implementation:

> l(a[1], b) %=% list(3, 4) Warning message: In assign(Name, r[[II]], pos = Envir) : only the first element is used as variable name

It doesn’t play nice with assignment functions.

It can be modified to call ‘<-’ directly:

'%=%.lbunch' = function(l, r, ...) { Envir = as.environment(-1) for (II in 1:length(l)) { do.call('<-', list(l[[II]], r[[II]]), envir=Envir) } }

And now all is good.

> l(attr(a, 'foo'), b) %=% list(3, 4) > a [1] 3 attr(,"foo") [1] 3

**leave a comment**for the author, please follow the link and comment on their blog:

**Struggling Through Problems » R**.

R-bloggers.com offers

**daily e-mail updates**about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.

Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.