Подтвердить что ты не робот

Как получить доступ к глобальной/внешней переменной сферы из функции R apply?

Я не могу заставить применить функцию доступа/модифицировать переменную, объявленную за пределами... что дает?

    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))

Результаты:

    age=11, weight=100
    age=12, weight=105
    age=13, weight=110
    i=0
    y=0, z=0
4b9b3361

Ответ 1

Используя оператор <<-, вы можете записать переменные во внешних областях:

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))

Результат здесь:

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

Обратите внимание, что использование <<- опасно, поскольку вы разбиваете область охвата. Сделайте это, только если это действительно необходимо, и если вы это сделаете, четко документируйте это поведение (по крайней мере, в больших сценариях)

Ответ 2

попробуйте выполнить следующие действия. Экспериментируйте со значением n. Я считаю, что для i он должен быть меньше, чем для 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