Using Get Inside Lapply, Inside a Function

Using get inside lapply, inside a function

Edit of 2013-08-05

Using sapply() instead of lapply(), simplifies this considerably:

foo4 <- function(a=1, b=5, h='coconut') {
frm <- formals(sys.function())
sapply(names(frm), get, envir=sys.frame(sys.parent(0)), simplify=FALSE)
}
foo4(b=0, h='mango')

This, though, without sapply() or lapply() might be the more elegant solution:

foo5 <- function(a=1, b=5, h='coconut') {
modifyList(formals(sys.function()), as.list(match.call())[-1])
}
foo5(b=0, h='mango')

Original post (2011-11-04)

After casting about a bit, this looks to be the best solution.

foo <- function(a=1, b=5, h='coconut') {
frm <- formals(foo)
parms <- lapply(names(frm), get, envir=sys.frame(sys.parent(0)))
names(parms) <- names(frm)
return(parms)
}
foo(b=0, h='mango')
# $a
# [1] 1

# $b
# [1] 0

# $h
# [1] "mango"

There's some subtle stuff going on here with the way that lapply scopes/evaluates the calls that it constructs. The details are hidden in a call to .Internal(lapply(X, FUN)), but for a taste, compare these two calls:

# With function matched by match.fun, search in sys.parent(0)
foo2 <- function(a=1, h='coconut') {
lapply(names(formals()),
get, envir = sys.parent(0))
}

# With anonymous function, search in sys.parent(2)
foo3 <- function(a=1, h='coconut') {
lapply(names(formals()),
FUN = function(X) get(X, envir = sys.parent(2)))
}

foo4(a=0, h='mango')
foo5(a=0, h='mango')

Unable to use apply function inside an lapply function in a shiny app

VitaminB16's answer delivers what you need, so you need to figure out how you want to represent it.

For instance, if you use the following code in your server (adapting VitaminB16's answer a bit):

output$data <- renderUI({
splitDFs<- split(iris, iris$Species)

sP <- data.frame(t(sapply(splitDFs, function(x) sapply(x, function(y) sum(!is.na(y))))))
sP <- cbind(data.frame(Metric = rownames(sP)), sP)
sP2 <- renderTable(sP)

return(list(sP2))

})

You get this:

Sample Image

Here, each row is a split in the data, and each column is a column in the original dataset. The cells represent the number of non-missing values in that combination.

  • The split is functioning as before.

  • Then first we use nested apply as Vitamin did to calculate the
    cross-sectional non-NA count.

    • We use sapply instead of lapply to get a matrix output instead of a
      list output, so we can easily coerce to a dataframe.
  • Before coercing, we transpose, so columns remain columns (you can
    play around with this if you like).

  • Then, we add in the row names as an explicit column. We do that
    through cbind since otherwise the Metric column would be at the end.

  • Then, we put it in a renderTable and pass that back.

    • Note that since this is now just one table, you could use renderTable
      and tableOutput directly instead of worrying about renderUI and
      uiOutput.

How to use lapply or a family of the apply function for calling a function within a function in R?

To avoid confusion, it is better to have anonymous function call

lapply(z, function(x) hrat(x, drat))

How to use lapply with a function that requires a vector as an argument

lapply takes a list as its first argument and a function as its second. Optional arguments for the function can be added as additional arguments to lapply.

By using match(c(1,3), k), you are calling match on c(1, 3) and your list k. What you want to do is to pass a function to lapply that will take a vector x as argument and return match(c(1, 3), x). lapply will then execute this function on each element of your list k.

This is how you should use lapply:

k <- list(c(2,0,2,1),c(3,0,2,0),c(0,1,2,0))
lapply(k, function(x) match(c(1,3), x))
# [[1]]
# [1] 4 NA
#
# [[2]]
# [1] NA 1
#
# [[3]]
# [1] 2 NA

R package: using lapply to do.call a list of internal functions

Following the comments on the question, I have a (partial) answer:

  1. do.call by default evaluates character arguments in parent.frame(), and when called inside lapply, this is a different environment than the one the tmp functions are defined in (though I'm not sure about the specifics)
  2. Supplying the current environment to do.call makes the lapply approach work:
    lapply(funs, do.call, args = list(x = "test"), envir = environment())


Related Topics



Leave a reply



Submit