Using get inside lapply, inside a function

前端 未结 3 749
萌比男神i
萌比男神i 2020-12-16 01:09

this may seem like a overly complicated question, but it has me driving me a little nuts for some time. It is also for curiosity, because I already have a way of doing what

相关标签:
3条回答
  • 2020-12-16 01:28

    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')
    
    0 讨论(0)
  • 2020-12-16 01:31

    This is adapted from @Josh O'Brien's solution above using sapply to automatically assign the correct names to the resulting list (saves one line of code):

    foo <- function(a=1, b=5, h='coconut') {
        frm <- formals(foo)
        parms <- sapply(names(frm), get, envir=sys.frame(sys.parent(-1)), simplify=FALSE)
        return(parms)
    }
    
    0 讨论(0)
  • 2020-12-16 01:34

    Just convert the current environment into a list:

    foo <- function(a=1, b=5, h='coconut') {
      as.list(environment())
    }
    foo(a = 0, h = 'mango')
    
    0 讨论(0)
提交回复
热议问题