我有一个我应用于矩阵的功能。但是这个向量是广泛的,我想用计数器来检查它的进度。
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,而且我想避免循环。
答案 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