7

Possible Duplicate:
function with multiple outputs

This seems like an easy question, but I can't figure it out and I haven't had luck in the R manuals I've looked at. I want to find dim(x), but I want to assign dim(x)[1] to a and dim(x)[2] to b in a single line.

I've tried [a b] <- dim(x) and c(a, b) <- dim(x), but neither has worked. Is there a one-line way to do this? It seems like a very basic thing that should be easy to handle.

Community
  • 1
  • 1
Eli Sander
  • 1,228
  • 1
  • 13
  • 29
  • I know it is cheating: `tmp <- dim(x); a <- tmp[1]; b <- tmp[2]` – sgibb Jul 25 '12 at 13:58
  • 2
    I'd take a look at [this question](http://stackoverflow.com/questions/1826519/function-returning-more-than-one-value). The shortest answer is no, R doesn't do that. The long answer is that you can always make it work for your specific use case. But there is no "multiple assignment" like in many other languages. – Justin Jul 25 '12 at 14:17
  • Thanks @Justin. I know other languages did this, so I was hoping there was an easy way. It's not a huge efficiency problem or anything, just one of R's slightly irritating "quirks" (of which there are many, much as I love the language!). – Eli Sander Jul 25 '12 at 14:24

4 Answers4

1

This may not be as simple of a solution as you had wanted, but this gets the job done. It's also a very handy tool in the future, should you need to assign multiple variables at once (and you don't know how many values you have).

Output <- SomeFunction(x)
VariablesList <- letters[1:length(Output)]
for (i in seq(1, length(Output), by = 1)) {
    assign(VariablesList[i], Output[i])
}

Loops aren't the most efficient things in R, but I've used this multiple times. I personally find it especially useful when gathering information from a folder with an unknown number of entries.

EDIT: And in this case, Output could be any length (as long as VariablesList is longer).

EDIT #2: Changed up the VariablesList vector to allow for more values, as Liz suggested.

MikeZ
  • 345
  • 1
  • 4
  • 15
  • This is a pretty good solution if you have a lot of pieces of output, although probably not worth it for my situation. I would probably replace your first line with `VariablesList <- letters[1:length(Output)]` though. – Eli Sander Jul 25 '12 at 15:07
  • Good idea, I've added that to my post. – MikeZ Jul 25 '12 at 15:32
1

You can also write your own function that will always make a global a and b. But this isn't advisable:

mydim <- function(x) {
  out <- dim(x)
  a <<- out[1]
  b <<- out[2]
}

The "R" way to do this is to output the results as a list or vector just like the built in function does and access them as needed:

out <- dim(x)

out[1]

out[2]

R has excellent list and vector comprehension that many other languages lack and thus doesn't have this multiple assignment feature. Instead it has a rich set of functions to reach into complex data structures without looping constructs.

Justin
  • 42,475
  • 9
  • 93
  • 111
0

Doesn't look like there is a way to do this. Really the only way to deal with it is to add a couple of extra lines:

temp <- dim(x)
a <- temp[1]
b <- temp[2]
Eli Sander
  • 1,228
  • 1
  • 13
  • 29
-1

It depends what is in a and b. If they are just numbers try to return a vector like this:

dim <- function(x,y) 
    return(c(x,y))
dim(1,2)[1]
# [1] 1
dim(1,2)[2]
# [1] 2

If a and b are something else, you might want to return a list

dim <- function(x,y)
    return(list(item1=x:y,item2=(2*x):(2*y)))
dim(1,2)[[1]]
[1] 1 2
dim(1,2)[[2]]
[1] 2 3 4

EDIT:

try this: x <- c(1,2); names(x) <- c("a","b")

chandler
  • 716
  • 8
  • 15
  • I'm a little confused about what you're suggesting. The `dim()` function is built-in, I just want to assign the dimensions to arbitrary objects `a` and `b` without doing that assignment after calling `dim()` – Eli Sander Jul 25 '12 at 14:06
  • Thanks for your suggestions-- `names()` only affects the column names of the output though. If you tried something like `a*3` after running that line, you would get an error. Unfortunately, I'm thinking that there isn't a built-in way to do this, so I'll just have to add a couple extra lines to deal with it. – Eli Sander Jul 25 '12 at 14:20