I want to include data argument within 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){
#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]])
return(c(`DeltaK0` = deltaK0))
}
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)
I know there is a workaround using with like
with(iris, Ploy(Sepal.Length = Sepal.Length, Sepal.Width = Sepal.Width,
Petal.Width = Petal.Width))
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, data = iris)
How can I achieve it?
CodePudding user response:
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]]
CodePudding user response:
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"
