Reputation: 8176
I want to include data argument within a custom R function. Right now I am using the following function
Ploy <- function(Sepal.Length = Sepal.Length, Sepal.Width = Sepal.Width,
Petal.Width = Petal.Width, Petal.Length = Petal.Length){
#Calculate some derived parameters
deltak <- (Sepal.Length - Sepal.Width)/390
ARk <- Petal.Width*2
dat <- cbind.data.frame(deltak, ARk)
#Fitting quadratic model
mod <- lm(deltak ~ poly(ARk, 2, raw = TRUE))
deltaK0 <- abs(mod$coefficients[[1]])
Ks <- Petal.Length - deltaK0
return(c(`DeltaK0` = deltaK0, `Ks` = Ks))
}
When I am calling the function I have to use iris$
like
Ploy(Sepal.Length = iris$Sepal.Length, Sepal.Width = iris$Sepal.Width,
Petal.Width = iris$Petal.Width, Petal.Length = iris$Petal.Length)
I know there is a workaround using with
like
with(iris, Ploy(Sepal.Length = Sepal.Length, Sepal.Width = Sepal.Width,
Petal.Width = Petal.Width, Petal.Length = Petal.Length))
But I want to have the call for the Ploy
function like
Ploy(Sepal.Length = Sepal.Length, Sepal.Width = Sepal.Width,
Petal.Width = Petal.Width, Petal.Length = Petal.Length, data = iris)
How can I achieve it?
Update
Taking clue from the answer of @user2554330, I have used the following code
Ploy <- function(data, Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = "Petal.Length"){
Sepal.Length = data[[Sepal.Length]]
Sepal.Width = data[[Sepal.Width]]
Petal.Width = data[[Petal.Width]]
Petal.Length = data[[Petal.Length]]
#Calculate some derived parameters
deltak <- (Sepal.Length - Sepal.Width)/390
ARk <- Petal.Width*2
dat <- cbind.data.frame(deltak, ARk)
#Fitting quadratic model
mod <- lm(deltak ~ poly(ARk, 2, raw = TRUE))
deltaK0 <- abs(mod$coefficients[[1]])
Ks <- Petal.Length - deltaK0
return(c(`DeltaK0` = deltaK0, `Ks` = Ks))
}
Now the function can be used like
Ploy(Sepal.Length = "Sepal.Length", Sepal.Width = "Sepal.Width",
Petal.Width = "Petal.Width", Petal.Length = "Petal.Length", data = iris)
Upvotes: 1
Views: 110
Reputation: 44
You can specify as many parameters (inputs) to your R functions as you like. The problem you encounter is because of how you are calling those parameters (inputs).
An example of a function statement might be as follows:
# Function declaration
Ploy <- function(sepal_lenght,sepal_width, petal_witdh, petal_length, data){
print(paste("sepal_lenght inside function is ", sepal_lenght))
print(paste("sepal_width inside function is ", sepal_width))
print(paste("petal_witdh inside function is ", petal_witdh))
print(paste("petal_length inside function is ", petal_length))
print(paste("Aditional data inside function is ", data))
}
# Running your function with concrete values
Ploy(10,20,3.4,66, 'complex object')
An example result would be:
[1] "sepal_lenght inside function is 10"
[1] "sepal_width inside function is 20"
[1] "petal_witdh inside function is 3.4"
[1] "petal_length inside function is 66"
[1] "Aditional data inside function is complex object"
That said, for your case, you could perform a function like this:
sepal <- data.frame(
"length" = 5.1,
"width" = 3.5
)
petal <- data.frame(
"length" = 1,4,
"width" = 0.2
)
# Function declaration
Ploy <- function(sepal, petal, data){
print(paste("sepal_lenght inside function is ", sepal$length))
print(paste("sepal_width inside function is ", sepal$width))
print(paste("petal_witdh inside function is ", petal$length))
print(paste("petal_length inside function is ", petal$width))
print(paste("Aditional data inside function is ", data))
}
# Running your function with concrete values, passing sepal and petal objects
Ploy(sepal, petal, 'more complex object')
So you will obtain:
[1] "sepal_lenght inside function is 5.1"
[1] "sepal_width inside function is 3.5"
[1] "petal_witdh inside function is 1"
[1] "petal_length inside function is 0.2"
[1] "Aditional data inside function is more complex object"
Upvotes: 1
Reputation: 44877
What you are asking for is "non-standard evaluation": you don't want to evaluate the expression Sepal.Length
in the standard way.
I'd advise against doing this. It's very difficult to get it right, so that you don't have weird behavior in some special cases. The tidyverse packages use it, and even though those packages are written by very smart people who have thought about it very carefully, it still has some weird bugs, e.g. handling ...
arguments.
Instead, ask your user to specify the column using a string name, e.g. their call looks like
Ploy(col1 = "Sepal.Length", col2 = "Sepal.Width",
col3 = "Petal.Width", data = iris)
Then within your function, using entirely standard evaluation, you can refer to those columns as
data[[col1]]
data[[col2]]
data[[col3]]
Upvotes: 4