4

我正在运行一个模拟,我需要跟踪特定条件的函数调用中出现的次数。我试图通过分配一个全局对象来实现这一点。如果您运行该函数,它会起作用,但如果您像我一样尝试lapply该函数,那么您将获得条件发生的所有时间的单一计数,而不是每次发生的list计数lapply

这是一个虚拟情况,其中出现的是数字的偶数:

FUN <- function(x){
    lapply(1:length(x), function(i) {
        y <- x[i]
        if (y %% 2 == 0){
            assign("count.occurrences", count.occurrences + 1, env=.GlobalEnv)   
        }
        print("do something")
    })
    list(guy="x", count=count.occurrences)
}

#works as expected
count.occurrences <- 0
FUN(1:10)


count.occurrences <- 0  
lapply(list(1:10, 1:3, 11:16, 9), FUN) 

#gives me...
#> count.occurrences
#[1] 9

#I want...
#> count.occurrences
#[1] 5  1  3  0

它在模拟中,所以速度是一个问题。我希望这尽可能快,所以我不接受全球任务的想法。

4

3 回答 3

8

与其分配给全局环境,为什么不分配给 insideFUN的环境呢?

FUN <- function(x){
    count.occurances <- 0
    lapply(1:length(x), function(i) {
        y <- x[i]
        if (y %% 2 == 0){
            count.occurances <<- count.occurances + 1
        }
        print("do something")
    })
    list(guy="x", count=count.occurances)
}

Z <- lapply(list(1:10, 1:3, 11:16, 9), FUN) 

然后你可以把计数拉出来。

> sapply(Z, `[[`, "count")
[1] 5 1 3 0
于 2012-08-07T16:36:46.367 回答
2

我没有对此进行任何基准测试,但是您是否尝试过仅使用for循环?我知道在 R 中通常不鼓励循环,但它们也不总是较慢。

FUN <- function(x) {
  count.occurrences = 0
  for (i in 1:length(x)) {
    y = x[i]
    if (y %% 2 == 0) {
      count.occurrences = count.occurrences + 1
    }
    print("do something")
  }
  list(guy="x", count=count.occurrences)
}

lapply(list(1:10, 1:3, 11:16, 9), FUN)
于 2012-08-07T16:24:25.230 回答
0

我可以这样得到:

count.occurances <- 0  
Z <-lapply(list(1:10, 1:3, 11:16, 9), FUN) 
diff(c(0, sapply(1:length(Z), function(x) Z[[x]]$count)))

我愿意接受更好的想法(更快)。

于 2012-08-07T16:23:34.960 回答