Passing a variable name to a function in R
I've recently discovered what I think is a better approach to passing variable names.
a <- data.frame(x = 1:10, y = 1:10)
b <- function(df, name){
eval(substitute(name), df)
}
b(a, x)
[1] 1 2 3 4 5 6 7 8 9 10
Update The approach uses non standard evaluation. I began explaining but quickly realized that Hadley Wickham does it much better than I could. Read this http://adv-r.had.co.nz/Computing-on-the-language.html
Passing variable name to a function in R
Use deparse/substitute
to convert the unquoted argument to string and then use [[
to pull the column as a vector, create the logical vector and subset with [
myf.subset <- function(data, xvar) {
xvar <- deparse(substitute(xvar))
data[data[[xvar]] == 0, , drop = FALSE]
}
-testing
> myf.subset(df, xvar = x)
x
3 0
5 0
12 0
18 0
20 0
24 0
25 0
28 0
29 0
32 0
33 0
35 0
36 0
37 0
39 0
41 0
42 0
43 0
47 0
48 0
49 0
51 0
55 0
57 0
58 0
62 0
63 0
65 0
66 0
67 0
69 0
70 0
71 0
73 0
74 0
75 0
76 0
80 0
82 0
84 0
87 0
88 0
90 0
92 0
94 0
97 0
99 0
In the updated code, the formula can be created with reformulate
or paste
myf.subset <- function(data, xvar, yvar, zvar) {
xvar <- deparse(substitute(xvar))
yvar <- deparse(substitute(yvar))
zvar <- deparse(substitute(zvar))
# new.data <- subset(data, xvar == 0)
new.data <- data[data[[xvar]] == 0, , drop = FALSE]
fmla <- reformulate(zvar, response = yvar)
# fmla <- as.formula(paste(yvar, zvar, sep = ' ~ '))
OLS <- lm(data = new.data, fmla )
return(OLS)
}
-testing
> myf.subset(df, xvar = x, yvar = y, zvar = z)
Call:
lm(formula = fmla, data = new.data)
Coefficients:
(Intercept) z
0.48000 -0.01333
R user-defined save load functions | Passing variable names as arguments using deparse(substitute)
You need to do the changes in both save
and load
functions. Use list
argument in save
function to save the data with the same variable names as passed value.
getSave <- function(folder, rdata){
val <- deparse(substitute(rdata))
save(list = val,
file = paste0("./", deparse(substitute(folder)), "/", val, ".RData"))
}
getSave(SData, x)
getSave(SData, y)
To load the data, specify the environment as global since by default the values are loaded in the called environment. Since you are loading the data in a function by default the values are loaded inside the function only.
getLoad <- function(folder, rdata){
load(paste0("./", deparse(substitute(folder)), "/", deparse(substitute(rdata)), ".RData"),
envir = .GlobalEnv)
}
getLoad(SData, x)
getLoad(SData, y)
So the issue was not related to deparse
, substitue
but how save
and load
functions work inside a user defined function.
How to assign function argument to variable name
You were close! There are multiple ways of subsetting dataframes, including using the [[.]]
notation (e.g., data[["var"]]
. Simply assigning a value to a new column initializes the column.
fun <- function(varname) {
data <- data.frame(a = c(1,2,3))
data[[varname]] <- sqrt(data$a)
data
}
fun("newvar")
Passing variable name to user-defined function that makes a plotly chart
When you call your function, you have to use real objects or strings. In other words, you have to pass the column names as strings.
From there you run into another issue. Once you make the column names strings Plotly will not connect columns to the SharedData
object without additional intervention.
Since I don't think you want the parameter name as the axes' labels, I added labels, as well.
Here is what you can do to make this work.
make_bar_chart <- function(shared_data, xvar, yvar){
plot_ly(data = shared_data,
hoverinfo = "none") %>%
add_trace(
x = ~.data[[xvar]], # <- tell plotly 'connect to the data object!'
y = ~.data[[yvar]], # <- here, too
type = "bar",
transforms = list(
list(
type = "aggregate",
groups = ~.data[[yvar]], # <- here, too
aggregations = list(
list(
target = "x", func = "avg", enabled = T))))
) %>%
layout(xaxis = list(title = xvar),
yaxis = list(title = yvar))
}
# pass non-environment variables as strings
make_bar_chart(bar_data_shared, "pct_increase", "category")
Passing column name as argument in function within pipes
You need to make use of non standard evaluation which is worth a quick read about. In this case you most likely need to !!
infront of var
in the mutate line.
Here's the line:
mutate(new_variable = !!sym(var) * 100)
Pass variable name to a function in r
You can use get
For instance
var1 <- get(paste(e, ".2", sep=""))
var2 <- get(paste(e, ".7", sep=""))
EDIT: as Aidan Cully correctly says then you should call your function as q("e")
(i.e. with a string)
Related Topics
Can't Loop with R's Leaflet Package to Produce Multiple Maps
Range Standardization (0 to 1) in R
Categorize Continuous Variable with Dplyr
How to Retry a Statement on Error
Ggplot Scale Color Gradient to Range Outside of Data Range
Optimized Rolling Functions on Irregular Time Series with Time-Based Window
How to Change .Libpaths() Permanently in R
Can the Value.Var in Dcast Be a List or Have Multiple Value Variables
Changing Values When Converting Column Type to Numeric
Merge Nearest Date, and Related Variables from a Another Dataframe by Group
Ggplot: Adding Regression Line Equation and R2 with Facet
Why (Or When) Is Rscript (Or Littler) Better Than R Cmd Batch
R Data.Table Apply Function to Rows Using Columns as Arguments