how to access global/outer scope variable from R apply function?

前端 未结 2 835
忘掉有多难
忘掉有多难 2020-12-03 02:44

I can\'t seem to make apply function access/modify a variable that is declared outside... what gives?

    x = data.frame(age=c(11,12,13), weight=c(100,105,11         


        
相关标签:
2条回答
  • 2020-12-03 03:19

    Using the <<- operator you can write to variables in outer scopes:

    x = data.frame(age=c(11,12,13), weight=c(100,105,110))
    x
    
    testme <- function(df) {
        i <- 0
        apply(df, 1, function(x) {
            age <- x[1]
            weight <- x[2]
            cat(sprintf("age=%d, weight=%d\n", age, weight))
            i <<- i+1   #this could not access the i variable in outer scope
            z <<- z+1   #this could not access the global variable
        })
        cat(sprintf("i=%d\n", i))
        i
    }
    
    z <- 0
    y <- testme(x)
    cat(sprintf("y=%d, z=%d\n", y, z))
    

    The result here:

    age=11, weight=100
    age=12, weight=105
    age=13, weight=110
    i=3
    y=3, z=3
    

    Note that the usage of <<- is dangerous, as you break up scoping. Do this only if really necessary and if you do, document that behavior clearly (at least in bigger scripts)

    0 讨论(0)
  • 2020-12-03 03:40

    try the following inside your apply. Experiment with the value of n. I believe that for i it should be one less than for z.

             assign("i", i+1, envir=parent.frame(n=2))
             assign("z", z+1, envir=parent.frame(n=3))
    



    testme <- function(df) {
        i <- 0
        apply(df, 1, function(x) {
            age <- x[1]
            weight <- x[2]
            cat(sprintf("age=%d, weight=%d\n", age, weight))
    
            ## ADDED THESE LINES
             assign("i", i+1, envir=parent.frame(2))
             assign("z", z+1, envir=parent.frame(3))
    
        })
        cat(sprintf("i=%d\n", i))
        i
    }
    

    OUTPUT

    > z <- 0
    > y <- testme(x)
    age=11, weight=100
    age=12, weight=105
    age=13, weight=110
    i=3
    > cat(sprintf("y=%d, z=%d\n", y, z))
    y=3, z=3     
    
    0 讨论(0)
提交回复
热议问题