user3693016
user3693016

Reputation: 61

How to convert character vector of variable names to list separated by commas in R

I have several data objects (three-dimensional arrays), for example object1, object2, object3.

These objects are listed in a character vector:

char <- c("object1","object2","object3")

I then need to grab the list of objects for use in a function that requires its inputs to be separated by commas:

output <- FancyFunction(object1,object2,object3,OtherFancyStuff)

How can I get R to automatically change the lower line of code when I change the upper line of code? I want to be able to add or delete objects from "char" and have it change accordingly in "output".

I don't know how to do this. The best I can do is:

output <- FancyFunction(get(char[1]),get(char[2]),get(char[3]),OtherFancyStuff)

But this is useless if the size of char changes.

Any thoughts?

Upvotes: 2

Views: 1701

Answers (2)

MrFlick
MrFlick

Reputation: 206232

The function do.call let's you call a function by passing a list of parameter values. In this case, you just need to create a list of the objects you want to pass and any additional parameters.

Since you already have the names of the objects you want to include in character vector form, the function mget() will return a list of objects with those names so that part is easy. You just need to add in your additional parameters.

So you can call your function with

do.call( FancyFunction, c(mget(char),OtherFancyStuff) )

Upvotes: 2

Gavin Simpson
Gavin Simpson

Reputation: 174813

I suppose something like this will work:

char <- c("object1","object2","object3")

## 2-d objects for illustration as I couldn't think of an array
## function that took arbitrary input vectors `...`
object1 <- object2 <- object3 <- array(1:25, dim = c(5,5))

do.call("rbind", mget(char))

which gives

> do.call("rbind", mget(char))
      [,1] [,2] [,3] [,4] [,5]
 [1,]    1    6   11   16   21
 [2,]    2    7   12   17   22
 [3,]    3    8   13   18   23
 [4,]    4    9   14   19   24
 [5,]    5   10   15   20   25
 [6,]    1    6   11   16   21
 [7,]    2    7   12   17   22
 [8,]    3    8   13   18   23
 [9,]    4    9   14   19   24
[10,]    5   10   15   20   25
[11,]    1    6   11   16   21
[12,]    2    7   12   17   22
[13,]    3    8   13   18   23
[14,]    4    9   14   19   24
[15,]    5   10   15   20   25

To pass in extra arguments, you need to modify this slightly, by concatenating the other arguments on the object returned by mget(char), for example:

c(mget(char), list(arg1 = "foo", arg2 = "bar", arg3 = 1:10))

> c(mget(char), list(arg1 = "foo", arg2 = "bar", arg3 = 1:10))
$object1
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    2    7   12   17   22
[3,]    3    8   13   18   23
[4,]    4    9   14   19   24
[5,]    5   10   15   20   25

$object2
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    2    7   12   17   22
[3,]    3    8   13   18   23
[4,]    4    9   14   19   24
[5,]    5   10   15   20   25

$object3
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    2    7   12   17   22
[3,]    3    8   13   18   23
[4,]    4    9   14   19   24
[5,]    5   10   15   20   25

$arg1
[1] "foo"

$arg2
[1] "bar"

$arg3
 [1]  1  2  3  4  5  6  7  8  9 10

where arg1 etc correspond to additional arguments needed by FancyFunction and need to be named as per the formal arguments you wish these to map to in the definition of FancyFunction. The call would then resemble:

OtherFancyStuff <- list(arg1 = "foo", arg2 = "bar", arg3 = 1:10)
do.call("FancyFunction", c(mget(char), OtherFancyStuff)

Does FancyFunction need 3 arguments or is it's first argument ...? If you have control over this, it might be worth rewriting FancyFunction to take ... as the first argument and extract out of it the various arguments, any number of which can now be supplied:

FancyFunction <- function(..., other) {
  dots <- list(...)
  ## work on components of 'dots', the length of which is number of args
  ## provided as ...
  ....
  return()
}

Upvotes: 5

Related Questions