首页 > 解决方案 > 如何在 R 中跟踪其他环境的值

问题描述

我正在尝试为在线课程分配作业,但我一直在尝试保持缓存值。基本上,会有两个函数:一个是闭包函数,并托管一个变量来跟踪缓存上的值。另一位负责管理矩阵。问题是程序似乎没有为每个矩阵保留 m 的值,并且总是认为缓存中已经存在值。如何跟踪缓存的值?

makeCacheMatrix <- function(x = matrix()) {
    m<-NULL
    set<-function(y){
        x<<-y
        m<<-NULL
    }
    get<-function()x
    inverse<-function(x) m<<-solve(x)
    cache<-function() m
    list(set=set(x),get=get(),inverse=inverse(x),cache=cache())
}


## Write a short comment describing this function
cacheSolve <- function(x, ...) {
        ## Return a matrix that is the inverse of 'x'
        n<-makeCacheMatrix(x)$cache
        if (!is.null(n)){
            print("Loading from cache")
            return(n)
        }
        else{
            makeCacheMatrix(x)$set
            data<-makeCacheMatrix(x)$get
            makeCacheMatrix(data)$inverse

            makeCacheMatrix(data)$cache
    }}

标签: rfunctionclosureslexical-scope

解决方案


目前尚不完全清楚您在这里尝试什么。我的猜测是你想要一个缓存,这样如果你需要在一个对象上运行一个资源密集型函数,那么你只需要运行一次,然后就可以访问存储的计算结果。无论计算是否已运行,您都希望使用相同的接口来访问结果。

你可以这样做:

store_matrix_for_cache <- function(x = matrix()) {
  m <<- NULL
  function()
  {
    x <<- x
    list(get = x, cache = m, solve = function() m <<- solve(x))
  }
}

get_cached_result <- function(cache, ...) 
{
  if (is.null(cache()$cache))
  {
    cat("Solving before returning from cache\n")
    cache()$solve()
  } 
  else 
  {
    cat("Loading from cache\n")
  }

  return(cache()$cache)
}

因此,让我们在一些示例数据上对其进行测试:

set.seed(69)
my_mat   <- matrix(sample(9), nrow = 3)

my_mat
#>      [,1] [,2] [,3]
#> [1,]    2    5    9
#> [2,]    4    1    6
#> [3,]    7    3    8

我们首先将矩阵写入缓存。注意我们的“昂贵”solve函数还没有被调用,所以这在计算上很便宜:

my_cache <- store_matrix_for_cache(my_mat)

当我们来提取结果时,第一次,我们将触发solve计算:

get_cached_result(my_cache)
#> Solving before returning from cache
#>           [,1]       [,2]       [,3]
#> [1,]  2.000000  1.0000000 -2.0000000
#> [2,] -1.727273 -0.4545455  1.5454545
#> [3,]  1.090909  0.1818182 -0.8181818

但是,我们第二次(以及以后)访问缓存时,我们不会触发该solve函数,而是返回存储的结果。

get_cached_result(my_cache)
#> Loading from cache
#>           [,1]       [,2]       [,3]
#> [1,]  2.000000  1.0000000 -2.0000000
#> [2,] -1.727273 -0.4545455  1.5454545
#> [3,]  1.090909  0.1818182 -0.8181818

另请注意,我们的访问器功能可以通过删除cat消息来缩短,现在我们很高兴它按预期工作:

get_cached_result <- function(cache, ...) 
{
  if (is.null(cache()$cache)) cache()$solve()
  cache()$cache
}

reprex 包(v0.3.0)于 2020 年 7 月 25 日创建


推荐阅读