R apply function with multiple parameters
Just pass var2 as an extra argument to one of the apply functions.
mylist <- list(a=1,b=2,c=3)
myfxn <- function(var1,var2){
var1*var2
}
var2 <- 2
sapply(mylist,myfxn,var2=var2)
This passes the same var2
to every call of myfxn
. If instead you want each call of myfxn
to get the 1st/2nd/3rd/etc. element of both mylist
and var2
, then you're in mapply
's domain.
apply function for multiple fixed parameter in R
We can use lapply
to loop over the lambda
lapply(lambda, function(x) myfunc(my_data, x, my_vec, 100))
If we are not using lambda function
lapply(lamdba, myfunc, para1 = my_data, para3 = my_ec, para4 = 100)
Apply function with multiple parameters and output variable
As @Greg mentions, the purpose of this code isn't clear. However, the question seems to relate to how apply()
works so here goes:
Basically, when any of the apply
family of functions is used, the user-enetered function (f()
, in this case) is applied to the subset of the data produced by apply
. So here, you've asked apply
to evaluate each row then call f()
- the first argument to f()
would then be a vector rather than the data frame your function requires.
Here's some functioning code:
col_1 <- c("A", "B", "C")
col_2 <- c("red", "blue", "black")
df <- data.frame(col_1, col_2)
f <- function(x) {
x[1]
x[2]
}
apply(df, 1, f)
This generates all of the values of the second column as a vector since x[2] is returned from the function and for each row, will represent the value in the second column.
If you want the arg1
row of results, you could simply use the following:
find_row <- function(df, row) {
df[row, ]
}
find_row(df, 1)
apply()
isn't required. Using a single function makes the code simpler to read and should be faster too.
passing several arguments to FUN of lapply (and others *apply)
If you look up the help page, one of the arguments to lapply
is the mysterious ...
. When we look at the Arguments section of the help page, we find the following line:
...: optional arguments to ‘FUN’.
So all you have to do is include your other argument in the lapply
call as an argument, like so:
lapply(input, myfun, arg1=6)
and lapply
, recognizing that arg1
is not an argument it knows what to do with, will automatically pass it on to myfun
. All the other apply
functions can do the same thing.
An addendum: You can use ...
when you're writing your own functions, too. For example, say you write a function that calls plot
at some point, and you want to be able to change the plot parameters from your function call. You could include each parameter as an argument in your function, but that's annoying. Instead you can use ...
(as an argument to both your function and the call to plot within it), and have any argument that your function doesn't recognize be automatically passed on to plot
.
How to apply a function with multiple arguments and create a dataframe?
Change your function to accept string arguments :
fre <- function(.data, var) {
abc <- questionr::na.rm(.data[, var])
abc <- questionr::freq(abc)
abc <- cbind(Label = rownames(abc), abc)
abc <- questionr::rename.variable(abc, "n", "Frequency")
abc <- questionr::rename.variable(abc, "%", "Percent")
abc <- tidyr::separate(abc, Label, into = c("Value", "Label"), sep = "] ")
row.names(abc) <- NULL
abc <- abc %>% dplyr::mutate(Value = gsub("\\[|\\]", "", Value)) %>%
dplyr::select(Label, Value, Frequency, Percent) %>%
select(Label, Percent)
abc$Percent <- paste0(round(abc$Percent), "%")
abc <- abc %>%
tidyr::pivot_wider(names_from = Label, values_from = Percent)
Label <- var_label(.data[[var]])
Name <- var
abc <- cbind(Name, Label, abc)
abc
}
Then pass column names to fre
function as string using lapply
.
cols <- c('Q03', 'Q06', 'Q07', 'Q08', 'Q10')
result <- do.call(rbind, lapply(cols, fre, .data = dat))
#Or a bit shorter
#result <- purrr::map_df(cols, fre, .data = dat))
result
# Name Label Strongly agree Agree Neither Disagree
#1 Q03 Standard deviations excite me 19% 26% 34% 17%
#2 Q06 I have little experience of computers 27% 44% 13% 10%
#3 Q07 All computers hate me 7% 34% 26% 24%
#4 Q08 I have never been good at mathematics 15% 58% 19% 6%
#5 Q10 Computers are useful only for playing games 14% 57% 18% 10%
# Strongly disagree
#1 3%
#2 6%
#3 8%
#4 3%
#5 2%
apply function with multiple arguments and variables
If we have to apply the 'k' for multiple columns, pass the columns in a list
res <- do.call(cbind, Map(function(l, k) rollmean(datt[,k], l, fill = NA),
1:2, list(c("x", "x2"))))
However, we don't an extra argument as the need is for looping the k
argument and the subset of data remains the same
do.call(cbind, lapply(1:2, rollmean, x = datt[c("x", "x2")], fill = NA))
send multiple arguments using apply function
Assuming you want to pass the row, and a single argument that is the same for each row:
manydo3 <- function(x, r1) NULL
apply(eq, 1, manydo3, r1=18)
If you want different values for the second argument for each row, then you want to split your matrix into rows and pass both the rows and your other argument with mapply
:
mapply(manydo3, split(eq, row(eq)), R)
where length(R) == nrow(eq)
(i.e. R contains r1, r2, etc).
Apply Function Using Multiple Changing Arguments in R
No need for apply
:
#define function
myfunc <- function(var1, var2, var3){
result <- var1*var2*var3
return(result)
}
#dummy data
dat <- data.frame(A=c(1,2,3),B=c(4,5,6),C=c(7,8,9))
#test function
myfunc(dat$A,dat$B,dat$C)
#output
[1] 28 80 162
Using apply/sapply on a user defined function with multiple parameters
So it works:
credit.dat <- read.csv("http://www.cs.uu.nl/docs/vakken/mdm/credit.txt")
y <- credit.dat[, 6]
sapply(credit.dat, FUN=best.split.point, y=y)
# > sapply(credit.dat, best.split.point, y=y)
# age married house income gender class
# 32.5 0.5 0.5 36.0 0.5 0.5
applying a function with multiple arguments over multiple paired variables in R
We can use mapply/Map
. We need to extract the columns based on the column names by passing the 'x_vars', 'y_vars' as arguments to Map
, apply the my_fun
on the extracted the vector
s, and assign it back to 'y_vars' in the original dataset
df[y_vars] <- Map(function(x,y) my_fun(df[,x], df[,y]), x_vars, y_vars)
Or this can be also written as
df[y_vars] <- Map(my_fun, df[x_vars], df[y_vars])
NOTE: Here, we are assuming that all the elements in 'x_vars' and 'y_vars' are columns in the original dataset. We would also state that using Map
will be much more faster and efficient than reshaping it to long and then do some conversion.
To provide a different approach, we can use the melt
from data.table
library(data.table)
dM <- melt(setDT(df), measure = list(x_vars, y_vars))[,
value3 := my_fun(value1, value2), variable]
Then, again, we need to dcast
it back to 'wide' format. So, it is requires more steps and not much easy
setnames(dcast(dM, rowid(variable)~variable,
value.var = c("value1", "value3"))[,variable := NULL][], c(x_vars, y_vars))[]
data
set.seed(24)
df <- as.data.frame(matrix(sample(c(1:5, "something 10.5",
"this -4.5", "what -5.2 value?"),
12*10, replace=TRUE), ncol=12, dimnames =
list(NULL, c(x_vars, y_vars))), stringsAsFactors=FALSE)
Related Topics
Missing Legend with Ggplot2 and Geom_Line
Data.Table with Two String Columns of Set Elements, Extract Unique Rows with Each Row Unsorted
Tidyverse Pivot_Longer Several Sets of Columns, But Avoid Intermediate Mutate_Wider Steps
Get Values and Positions to Label a Ggplot Histogram
Check for Installed Packages Before Running Install.Packages()
How to Use Objects from Global Environment in Rstudio Markdown
Remove Multiple Objects with Rm()
Split Up '...' Arguments and Distribute to Multiple Functions
Linear Regression Loop for Each Independent Variable Individually Against Dependent
Display a Time Clock in the R Command Line
Adaptive Moving Average - Top Performance in R
Comma Separator for Numbers in R