lmocsi
lmocsi

Reputation: 1096

Variables for multiple parameters in R functions

I'd like to use a variable (xdata) to define, which data to display with the vioplot function. Tried the below ways but unfortunately, they do not work. How can I achieve this?

library(vioplot)
x1 = mtcars$mpg[mtcars$cyl==4]
x2 = mtcars$mpg[mtcars$cyl==6]
x3 = mtcars$mpg[mtcars$cyl==8]
xdata = paste("x1","x2","x3",sep=",") # Try 1
xdata = c("x1","x2","x3")             # Try 2
vioplot(xdata, names=c("4 cyl", "6 cyl", "8 cyl"),col="grey")

Upvotes: 1

Views: 154

Answers (3)

rovyko
rovyko

Reputation: 4587

I came to this question trying to figure out how to save a configuration of parameters that you would have passed into a function, and pass them on demand in a different line. The question and top answer weren't initially clear to me, so I have a simple demonstration for those just starting to learn R.

Let's say for example that you have the function substr that takes parameters x, start, and stop.

Instead of calling substr("Hello World", 2, 5) to get "ello", we can save the parameters into a list and call the function with the parameters using do.call:

params <- list("Hello World", 2, 5)
do.call(substr, params)
>> "ello"

If you only want to save start and stop, you can prepend the first argument with the combine function c:

params <- list(2, 5)
do.call(substr, c("Hello World", params))
>> "ello"

You can also add named arguments to the list the same way you specify parameters in a function call:

params <- list(stop=5, x="Hello World", start=2)
do.call(substr, params)
>> "ello"

And the list can mix named and non-named parameters:

params <- list("Hello World", start=2, stop=5)
do.call(substr, params)
>> "ello"

If you need more complex logic, you can also wrap your call in a factory function:

make_substr <- function(start, stop){
  return(
    function(string) {
      substr(string, start, stop)
    }
  )
}
substr_2_5 <- make_substr(2, 5)

substr_2_5("Hello World")
>> "ello"
substr_2_5("Goodbye")
>> "oodb"

Upvotes: 0

Anders Ellern Bilgrau
Anders Ellern Bilgrau

Reputation: 10233

If you really need to pass the data as a variable, the do.call function will do the trick in a manner like this:

library("vioplot")
x1 <- mtcars$mpg[mtcars$cyl==4]
x2 <- mtcars$mpg[mtcars$cyl==6]
x3 <- mtcars$mpg[mtcars$cyl==8]

xdata <- list(x1, x2, x3, names=c("4 cyl", "6 cyl", "8 cyl"), col="grey")
do.call(vioplot, xdata)

Or is it important that the variables to be plotted are passed as a character?

EDIT: To do it more dynamically, you can du something like this:

cyls <- c(4, 6, 8)
cyldata <- lapply(cyls, function(cyl) mtcars$mpg[mtcars$cyl == cyl])
xdata <- c(cyldata, list(names=paste(cyls, "cyl"), col="grey"))
do.call(vioplot, xdata)

The key thing is that you cyldata equivalent is a list.

Upvotes: 1

mkt
mkt

Reputation: 437

It's easier than that! No need to paste/bind/concatenate x1, x2 and x3 together.

vioplot(x1,x2,x3, names=c("4 cyl", "6 cyl", "8 cyl"),col="grey")

Upvotes: 0

Related Questions