Applying a function with two arguments using Lapply - r

I have created a test function, called testFunc which expects two arguments.
testFunc<-function(x,y){
length(x)
nrow(y)
}
Now I want to use lappy to apply this function to a list, keeping the y argument fixed.
Consider a test list, testList:
testList<-list(a=c(1,2,3,4,5,5,6),b=c(1,2,4,5,6,7,8))
Can we use lapply to run testFunc on testList$a and testList$b with same value of y?
I tried this call:
lapply(X = testList, FUN = testFunc, someDataFrame)
But I am always getting the length of someDataFrame as the output. Am I missing something obvious.

Change your function to
testFunc<-function(x,y){
return(c(length(x), nrow(y)))
}
By default, a R function returns the last evaluated value

Simplest way, use a named variable:
lapply(X = testList, FUN=testFunc, y=someDataFrame)

Related

inverting an index using clusters

This code is about inverting an index using clusters.
Unfortunately I do not understand the line with recognize<-...
I know that the function Vectorize applies the inner function element-wise, but I do not understand the inner function here.
The parameters (uniq, test) are not defined, how can we apply which then? Also why is there a "uniq" as text right after?
slots <- as.integer(Sys.getenv("NSLOTS"))
cl <- makeCluster(slots, type = "PSOCK")
inverted_index4<-function(x){
y <- unique(x)
recognize <- Vectorize(function(uniq,text) which(text %in% uniq),"uniq",SIMPLIFY = F)
y2 <- parLapply(cl, y, recognize, x)
unlist(y2,recursive=FALSE)
}
The
Vectorise()
function is just making a new element wise, vectorised function of the custom function
function(uniq,text) which(text %in% uniq).
The 'uniq' string is the argument of that function that you must specify you want to iterate over. Such that now you can pass a vector of length greater than one for uniq, and get returned a list with an element for the output of the function evaluated for every element of the input vector uniq.
I would suggest the author make the code a little clearer, better commented etc. the vectorise function doesn't need to be inside the function call necessarily.
Note
ParLapply()
isn't a function I recognise. But the x will be passed to the recognise function and the second argument text should presumably be defined earlier on, in the global environment, .GlobalEnv().

combining do.call() and debug() prints all arguments contents

I am using R and trying to debug a function that I call with do.call() for convenience.
Combining do.call() and browser() is problematic. Basically, all the elements of the list of arguments passed to do.call() are printed, which, if the list contains for example a very large data table, is not sustainable.
Here is a reprex. I create a simple getsum() function that sums elements of a vector. I create a func() function that calls getsum() for a list of vectors.
#getsum returns the sum of a vector's elements
#func returns the vector of the sum of a list of vectors
func <- function(vec_list){
browser()
sums = lapply(FUN=getsum, X=vec_list)
sum = unlist(sums)
return(sum)
}
getsum <- function(vec){
sum = sum(vec)
return(sum)
}
args = list(vec_list=list(rnorm(5), rnorm(5)))
do.call(func, args)
That's the output I get :
Called from: (function(vec_list){
browser()
sums = lapply(FUN=getsum, X=vec_list)
sum = unlist(sums)
return(sum)
})(vec_list = list(c(-0.0801864335418185, 0.448324209935905,
-2.86518616779484, -0.359284963520417, -0.620062639582574), c(1.74835180362954,
-0.904288222154223, 0.746007117029027, 0.625889703799832, -0.908748727897187
)))
Browse[1]>
One might tell me "why are you using do.call()?". Indeed, if I simply call the function myself, the problem does not arise (see below). In this example I don't need to use do.call(), but sometimes it's extremely convenient.
#instead of do.call() use :
func(vec_list=args$vec_list)
The output is then :
Called from: func(vec_list = args$vec_list)
Browse[1]>
EDIT :
I have tried the argument browser(skipCalls=TRUE) that solves the problem but defies the purpose of browser(). It makes R executing all the function's command at once. Other suggestions welcome.

Modify elipsis in R

I have a problem with elipsis usecase. My function accepts list of objects, let's call them objects of class "X". Now, objects X are being processed inside of my function to class "Xs", so I have list of "Xs" objects. Function that I import from other package can compute multiple "Xs" objects at once but they have to be enumerated (elipsis mechanic), not passed as list. Is there a way how to solve it? I want something like this
examplefun <- function(charlist){
nums <- lapply(charlist, as.numeric)
sum(... = nums)
}
Of course example above throws an error but it shows what i want to achieve. I tried to unlist with recursive = FALSE ("X" and "Xs" are the list itself) but it does not work.
If there is no solution then:
Let's assume I decideed to accept ... insted of list of "X" objects. Can I modify elipsis elements (change them to "Xs") and then pass to function that accepts elipsis? So it will look like this:
examplefun2 <- function(...){
function that modify object in ... to "Xs" objects
sum(...)
}
In your first function, just call sum directly because sum works correctly on vectors of numbers instead of individual numbers.
examplefun <- function (charlist) {
nums <- vapply(charlist, as.numeric, numeric(1L))
sum(nums)
}
(Note the use of vapply instead of lapply: sum expects an atomic vector, we can’t pass a list.)
In your second function, you can capture ... and work with the captured variable:
examplefun2 <- function (...) {
nums <- as.numeric(c(...))
sums(nums)
}
For more complex arguments, Roland’s comment is a good alternative: Modify the function arguments as a list, and pass it to do.call.

R mapply with named arguments

One fear I have when using mapply in R is that I may mess up the order of arguments & hence unconsciously generate garbage results.
mydata<-data.frame(Temperature=foobar,Pressure=foobar2)
myfunction<-function(P,T)
{
....
}
mapply(FUN = myfunction,mydata$Temperature,mydata$Pressure)
Is there a way to utilize named arguments to avoid this sort of error via mapply?
If we need to match the function arguments, name the arguments for Map/mapply with the arguments of the function
mapply(FUN = myfunction,T=mydata$Temperature,P=mydata$Pressure)
We can apply the function directly instead of mapply though (based on the example provided below in my post)
do.call(myfunction, unname(mydata[2:1]))
data
mydata <- data.frame(Temperature = 1:5, Pressure = 16:20)
myfunction <- function(P, T) {P*5 + T*10}

Apply a multi-argument function to a vector, varying only one argument

I would like to apply a function to a vector. My function takes multiple arguments, but I can keep the arguments the same throughout.
Here's what I've come up with, but it doesn't work. I've seen some things using mapply -- I'm not sure if that's what I need though.
add = function(x, y) x+y
sapply(1:5, add(y = 10))
In general you can give additional arguments of a function to sapply like this.
sapply(1:5, add, y=10)
Just write the function name and after that you can give any number of arguments directly within sapply itself

Resources