在函数内部实现计数器检查进度

时间:2015-02-12 22:14:43

标签: r

我有一个我应用于矩阵的功能。但是这个向量是广泛的,我想用计数器来检查它的进度。

N = 10
j = 0

functionX <- function(a,b,c) {

... stuff here ...

j<- j+1
print(paste(j/N,'%'))

}

a <- mapply(functionX, a[1:10,1],b[1:10,2],c[1:10,3])

但是这种方法不起作用,因为j永远不会大于1,而且我想避免循环。

2 个答案:

答案 0 :(得分:3)

问题出在functionX内,您正在为j分配值,因此您还定义了一个新的j变量,该变量仅存在于函数环境中且与在j之外定义的functionX

如果您想更改外部j,可以执行以下操作:

j <<- j+1

然而,最好不要修改父环境中的变量,所以我建议你传递一个新的变量来表示迭代计数器,例如: :

N = 10

functionX <- function(iteration,a,b,c) {
    # elaboration here
    print(paste( (iteration/N) * 100,'%'))
}

a <- mapply(functionX, 1:10, a[1:10,1],b[1:10,2],c[1:10,3])

答案 1 :(得分:2)

写入全局环境绝不是一个好主意,所以使用一个返回函数的函数。

counter = function(FUN, report=10) {
    j <- 0L                      # initialize the counter
    function(...) {              # a function that takes '...' and...
        j <<- j + 1L             # increment j in a containing env
        if ((j %% report) == 0L)
            message(j)
        FUN(...)                 # ...passes all args '...' to FUN
    }
}

j <<- j + 1表示,对于赋值,首先查看定义函数的环境,而不是函数本身。行j <- 0L服务器作为<<-查找j的一种中断 - 它在此环境中查找并更新它。如果未找到j,则<<-运算符将继续在定义环境中查找符号,直到到达全局环境。

行动中:

> x = sapply(1:20, counter(c, 5))    # concatenate elements c()
5
10
15
20
> x
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
> countedc = counter(c)
> x = integer(); for (i in 1:12) x = countedc(x, i)
10
> for (i in 1:9) x = countedc(x, i)
20
> x
 [1]  1  2  3  4  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9

也可以使用?txtProgressBar。如果FUN对其参数使用“非标准评估”,则可能会出现问题,例如subset()

矩阵运算很少需要很长时间;也许你正在迭代,但应该使用矢量化计算?

请注意,我定义并命名为j的任何全局变量都将保持不变

> j <- 42   # Yes! the meaning of life. Don't lose this!
> countedc(x, 0)
 [1]  1  2  3  4  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9  0
> j         # Would have been clobbered if counter used global env
[1] 42