R Apply Function with Multiple Parameters

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 vectors, 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



Leave a reply



Submit