In this piece of code, it uses list as what appears to be a function to capture functions created upstream of it. Not entirely sure what good is it for nor how each of the pieces fit together. Can someone clarify what this is doing.
makeCacheMatrix <- function(x = matrix()) {
j <- NULL
set <- function(y){
x <<- y
j <<- NULL
}
get <- function()x
setInverse <- function(inverse) j <<- inverse
getInverse <- function() j
list(set = set, get = get, #list of functions
setInverse = setInverse,
getInverse = getInverse)
}
Related
I'm looking to deal with call evaluations but am out of my depth when it comes to S3 Methods. Basically, I am wondering why a variable that I pass to a function call is not evaluated but rather remains the name of the variable rather than it's value. And all of this depends on whether I name the variable in the function or not.
Let me illustrate with a short example:
I first create a quick function to create a sample class to be used with S3 Methods:
create_myS3 <- function(a, b){
out <- list()
out$a <- a
out$b <- b
class(out) <- "myS3"
return(out)
}
Now the set-up that I am interested in features a number of functions within each other. I first create an S3 method for this myS3 class, let's call it m and we define a specific routine for the myS3 class as well as a default method. Note that the myS3 version calls the default version.
m <- function(x, ...){UseMethod("m")}
m.myS3 <- function(x, estimator = NULL){
y <- list()
y$a <- x$a + 1
y$b <- x$b + 1
out <- m.default(y,
estimator)
return(out)
}
m.default <- function(x, estimator = NULL, ...){
out <- list()
out$call <- sys.call()
out$result <- x$a - x$b
out$aux$estimator <- estimator
return(out)
}
Now that we have defined the functions, we can look at the results function that I'm interested in:
h <- function(x){
out <- list()
out$result_call <- if(is.null(x$call$estimator)){"Success"}else{"Fail"}
out$result_list <- if(is.null(x$aux$estimator)){"Success"}else{"Fail"}
return(out)
}
It's entire purpose is to check whether the estimator element is in the object it is passed to and to give a message based on that.
Ok, now let's put it all together:
g <- function(x){
object <- m(x)
out <- h(object)
return(out)
}
initial <- create_myS3(10,5)
g(initial)
The g() function now calls m() on the input, which was created with the create_myS3 function - so is of class myS3 and is therefore passed to m.myS3 before it is passed to m.default. The resulting object is then passed to h() - in all cases we have not set the estimator argument, which then defaults to NULL and both my check statements in h() return Success.
Now all I do is change one tiny thing: I now modify m.myS3 to call the m.default not just with the order of the input variables but now I also specify the option - in my mind the more robust way. So to clarify, from this m.default(y, estimator) I change it to m.default(x = y, estimator = estimator).
This change then changes my results from h() to Fail for the evaluation if(is.null(x$call$estimator)){"Success"}else{"Fail"} while if(is.null(x$aux$estimator)){"Success"}else{"Fail"} results in Success.
The reason for this is that the call statement evaluates to estimator rather than to its true value NULL.
Is there an easy way to evaluate this call to its true value (I have tried eval or deparse)? Or even better is there are a way to ensure that in m.myS3 the value is always passed rather than the variable?
Here below is the total code for convenience:
create_myS3 <- function(a, b){
out <- list()
out$a <- a
out$b <- b
class(out) <- "myS3"
return(out)
}
m <- function(x, ...){UseMethod("m")}
m.myS3 <- function(x, estimator = NULL){
y <- list()
y$a <- x$a + 1
y$b <- x$b + 1
out <- m.default(y,
estimator)
return(out)
}
m.default <- function(x, estimator = NULL, ...){
out <- list()
out$call <- sys.call()
out$result <- x$a - x$b
out$aux$estimator <- estimator
return(out)
}
h <- function(x){
out <- list()
out$result_call <- if(is.null(x$call$estimator)){"Success"}else{"Fail"}
out$result_list <- if(is.null(x$aux$estimator)){"Success"}else{"Fail"}
return(out)
}
g <- function(x){
object <- m(x)
out <- h(object)
return(out)
}
initial <- create_myS3(10,5)
g(initial)
$result_call
[1] "Success"
$result_list
[1] "Success"
## Changing m.myS3 (only change is to name the option of function m.default)
m.myS3 <- function(x, estimator = NULL){
y <- list()
y$a <- x$a + 1
y$b <- x$b + 1
out <- m.default(x = y,
estimator = estimator)
return(out)
}
g(initial)
$result_call
[1] "Fail"
$result_list
[1] "Success"
makeCacheMatrix <- function(x = matrix()) {
invm <- NULL
set <- function(y) {
x <<- y
invm <<- NULL
}
get <- function() x
setinverse <- function(solve) invm <<- solve()
getinverse <- function() invm
list(set = set, get = get,
setinverse = setinverse,
getinverse = getinverse)
}
cacheSolve <- function(x, ...) {
invm <- x$getinverse()
if(!is.null(invm)) {
message("getting cached matrix")
return(invm)
}
unit <- x$get()
invm <- solve(unit, ...)
x$setinverse(invm)
invm
}
In the test run, I've created a 4/4 matrix which was then stored with the first function. The second function should check if the matrix is cached, if so, print a message and use the stored matrix. I'd like to know what could possibly cause the error displayed below. I have no idea why the data don't get passed to the solve function.
> test <- matrix(rnorm(16, 3), 4, 4)
> test
[,1] [,2] [,3] [,4]
[1,] 2.654912 4.085775 3.1288214 5.059539
[2,] 3.252612 3.403775 0.9990708 1.623138
[3,] 1.705998 3.586488 3.3337772 1.849144
[4,] 2.040830 4.815228 4.1713251 2.294179
> test2 <- makeCacheMatrix(test)
> cacheSolve(test2)
Error in solve.default() : argument "a" is missing, with no default
When you call x$setinverse(invm), you are passing in a matrix object. But in the function setinverse, you are calling its one argument as a function, using solve(). Unfortunately, while solve at that point refers to the object passed originally as invm, R is smart-enough to know that solve() is meant to use a function and therefore is referring to base::solve and not your matrix. If you run base::solve() you will get the same error. So your problem is that your setinverse is wrong.
If you instead assign setinverse <- function(z) invm <<- solve(z), it seems to operate without error. Edit: actually, I think you're just using this as a "setter" function, so it should really be setinverse <- function(solve) invm <<- solve (or function(z) invm <<- z, your call).
Note: I haven't thought through the whole process to know if this is truly what you want to do.
Functions:
makeCacheMatrix <- function(x = matrix()) {
invm <- NULL
set <- function(y) {
x <<- y
invm <<- NULL
}
get <- function() x
setinverse <- function(z) invm <<- z
getinverse <- function() invm
list(set = set, get = get,
setinverse = setinverse,
getinverse = getinverse)
}
# cacheSolve as previously defined
Reproducible running (I suggest you use set.seed next time):
set.seed(42)
test <- matrix(rnorm(16, 3), 4, 4)
test
# [,1] [,2] [,3] [,4]
# [1,] 4.37095845 3.40426832 5.01842371 1.61113930
# [2,] 2.43530183 2.89387548 2.93728590 2.72121123
# [3,] 3.36312841 4.51152200 4.30486965 2.86667866
# [4,] 3.63286260 2.90534096 5.28664539 3.63595040
test2 <- makeCacheMatrix(test)
cacheSolve(test2)
# [,1] [,2] [,3] [,4]
# [1,] 0.819557500 1.961377325 -1.416577665 -0.714220507
# [2,] -0.162978899 -0.332156840 0.713223804 -0.241513973
# [3,] -0.343049934 -1.761166112 0.897525201 0.762466368
# [4,] -0.189839546 0.866424154 -0.459528758 0.073008724
It works! Thank you so much!
What I still don't get though is why the mean() function doesn't need this specification and still can refer to an object. Originally the code went like this:
makeVector <- function(x = numeric()) {
m <- NULL
set <- function(y) {
x <<- y
m <<- NULL
}
get <- function() x
setmean <- function(mean) m <<- mean
getmean <- function() m
list(set = set, get = get,
setmean = setmean,
getmean = getmean)
}
cachemean <- function(x, ...) {
m <- x$getmean()
if(!is.null(m)) {
message("getting cached data")
return(m)
}
data <- x$get()
m <- mean(data, ...)
x$setmean(m)
m
}
I'm new to R and I'm just figuring out environments and how to play around with them. In the code below, I understand that we are creating this list of 4 functions. But in this environment of makeVector, there is an object created, m and is assigned to null intially. What I don't understand (coming from a C language coder) is, how does this m stored?
I understand that makeVector has its own environment and has 6 things under it - x, m, set, get, setmean, getmean.
makeVector <- function(x = numeric()) {
m <- NULL
set <- function(y) {
x <<- y
m <<- NULL
}
get <- function() x
setmean <- function(mean) m <<- mean
getmean <- function() m
list(set = set, get = get,
setmean = setmean,
getmean = getmean)
}
For example,
x1 <- makeVector(as.numeric(1:4))
x2 <- makeVector(as.numeric(1:5))
Now, my question is, does x1 and x2 both have their own copies of m or do they share the same object m?
Again, if they do have different copies of m, isn't makeVector like a class in C, with its own objects and functions? Can someone clarify, because I'm having a very tough time figuring it out myself.
I'm trying to cache the inverse of matrix:
makeCacheMatrix <- function(x = matrix()) {
m <- NULL
set <- function(y) {
x <<- y
m <<- NULL
}
get <- function() x
setinverse <- function(inverse) m <<- inverse
getinverse <- function() m
list(set = set, get = get, setinvervse = setinverse, getinverse = getinverse)
}
cacheSolve <- function(x, ...) {
m <- x$getinverse()
if (! is.null(m)) {
message("getting cached data")
return(m)
}
data <- x$get()
m <- solve(data, ...)
x$setinverse(m)
m
}
But got the following errors:
**Error in x$setinverse(m) : attempt to apply non-function**
How to fix this? Thanks!
the following code worked for me
rm(list = ls())
makeCacheMatrix <- function(ma = matrix()) {
im <- NULL
setMatrix <- function(y) {
ma <<- y
im <<- NULL
}
getMatrix <- function() ma
setinverse <- function(inv) im <<- inv
getinverse <- function() im
list(setMatrix = setMatrix,
getMatrix = getMatrix,
setinverse = setinverse,
getinverse = getinverse)
}
cacheSolve <- function(x, ...) {
im <- x$getinverse()
if (!is.null(im)) {
message("getting cached inverse matrix")
return(im)
}
data <- x$getMatrix()
i <- solve(data, ...)
x$setinverse(i)
i
}
##testing the functions
B <- matrix(c(1,2,3,4),2,2)
B1 <- makeCacheMatrix(B)
cacheSolve(B1) #inverse returned after computation, no message
cacheSolve(B1) #inverse returned from cache and message is printed here
B2 <- makeCacheMatrix(-B)
cacheSolve(B1)
cacheSolve(B2)
I am following a Data Science course on Coursera and I have a question regarding one of the assignments where I have to inverse a Matrix and then cache that result.
Basically I have been googling away and I found the answer but there are parts of the answer that I do not yet understand. For this reason I don't want to submit my assignment yet since I don't want to submit anything that I do not fully understand.
The part that I do not understand from the code below is the part where setInverse is defined. where does the 'function(inverse) inv' come from? especially the 'inverse' was never defined?
After this a list is returned which does not make much sense to me as well?
If someone could take the time to explain this function to me I would be very grateful!
makeCacheMatrix <- function(x = matrix()) {
inv <- NULL
set <- function(y) {
x <<- y
inv <<- NULL
}
get <- function() x
setInverse <- function(inverse) inv <<- inverse
getInverse <- function() inv
list(set = set,
get = get,
setInverse = setInverse,
getInverse = getInverse)
}
## Write a short comment describing this function
cacheSolve <- function(x, ...) {
## Return a matrix that is the inverse of 'x'
inv <- x$getInverse()
if (!is.null(inv)) {
message("getting cached data")
return(inv)
}
mat <- x$get()
inv <- solve(mat, ...)
x$setInverse(inv)
inv
}
I don't know your exact assignment, but I would change your function slightly:
makeCacheMatrix <- function(x = matrix()) {
inv <- NULL
set <- function(y) {
x <<- y
inv <<- NULL
}
get <- function() x
setInverse <- function() inv <<- solve(x) #calculate the inverse
getInverse <- function() inv
list(set = set,
get = get,
setInverse = setInverse,
getInverse = getInverse)
}
You can then use it like this:
funs <- makeCacheMatrix()
funs$set(matrix(1:4, 2))
funs$get()
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
funs$setInverse()
funs$getInverse()
# [,1] [,2]
#[1,] -2 1.5
#[2,] 1 -0.5
The exercise is probably intended to teach you closures. The point is that x and inv are stored in the enclosing environment of the set, get, setInverse, getInverse functions. That means the environment within which they were defined, i.e., the environment created by the makeCacheMatrix() call. See this:
ls(environment(funs$set))
#[1] "get" "getInverse" "inv" "set" "setInverse" "x"
As you see not only are the four functions in this environment, but also the x and inv objects (a consequence of using <<-). And the get and getInverse functions only fetch these from their enclosing environment.