I got 2 functions of code here :
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)
}
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
}
So when I try to test my function, I will provide a little bit more detail at here:
> source("makeCacheMatrix.R")
> my_matrix <- makeCacheMatrix(matrix(1:4, 2, 2))
> my_matrix$get()
[,1] [,2]
[1,] 1 3
[2,] 2 4
> my_matrix$getInverse()
NULL
> cacheSolve(my_matrix)
Error in x$setmean(inv) : attempt to apply non-function
May I know why when I run the function cacheSolve(my_matrix), it will shows up the error like that?
Related
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 have three functions and one function is made out of the other two by using useMethod().
logReg <- function(x, ...) UseMethod("logReg")
logRec.numeric <- function(x, y) {
print(x)
}
logReg.formula <- function(formula, data) {
print(formula)
}
My functions are a bit more complex but does not matter for my question. I want logReg to give me additionaly the original function call as output (not the function call of logReg.numeric oder logReg.formula). My first try was:
logReg <- function(x, ...) {
out <- list()
out$call <- match.call()
out
UseMethod("logReg")
}
But it does not work. Can someone give me a hint how to solve my problem?
Here's another way :
logReg <- function(x, ...) {
logReg <- function(x, ...) UseMethod("logReg")
list(logReg(x,...), call=match.call())
}
res <- logReg(1,2)
# [1] 1
res
# [[1]]
# [1] 1
#
# $call
# logReg(x = 1, 2)
#
You can make it work with atttibutes too if you prefer.
Try evaluating it explicitly. Note that this preserves the caller as the parent frame of the method.
logReg <- function(x, ...) {
cl <- mc <- match.call()
cl[[1]] <- as.name("logReg0")
out <- structure(eval.parent(cl), call = mc)
out
}
logReg0 <- function(x, ...) UseMethod("logReg0")
logReg0.numeric <- function(x, ...) print(x)
logReg0.formula <- function(x, ...) print(x)
result <- logReg(c(1,2))
## [1] 1 2
result
## [1] 1 2
## attr(,"call")
## logReg(x = c(1, 2))
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 trying to run this example for the R Programming course on coursEra. However when I try to determine whether or not the matrix is square I get error saying "Error in is.square.matrix(x) : argument x is not a matrix"
My code is below:
library(matrixcalc)
##non-square matrix
NCols <- sample(3:6, 1)
NRows <- sample(2:8, 1)
myMat <- matrix(runif(NCols*NRows), ncol=NCols)
is.square.matrix(myMat)
## functions
makeMatrix <- function(x = matrix()) {
m <- NULL
set <- function(y) {
x <<- y
m <<- NULL
}
get <- function() x
setInv <- if (is.square.matrix(x) == TRUE) {
function(solve) m <<- solve
}
{
function(ginv) m <<- ginv
}
getInv <- function() m
list(x, set = set, get = get,
setInv = setInv,
getInv = getInv)
}
cacheMatrix <- function(x, ...) {
m <- x$getInv()
if(!is.null(m)) {
message("getting cached data")
return(m)
}
data <- x$get()
m <- if (is.square.matrix(x) == TRUE) {
solve(data, ...)
}
{
ginv(data, ...)
}
x$setInv(m)
m
}
## run functions for matrix
notSquare <- makeMatrix(myMat)
cacheMatrix(notSquare)
##check
ginv(myMat)
Then I get the error:
Error in is.square.matrix(x) : argument x is not a matrix
I am a beginner so not sure how to get the sentInv to recognize and check if the matrix is square or not.
Brian
Nevermind. In the makeMatrix function needed to replace x with (x = matrix()) and in the cacheMatrix replace x with (data)
Here's the answer. I just made the function (x) instead of function(x = matrix()) and 'data' is the variable to pull the matrix in the cache function need to have that me the input.
##non-square matrix
NCols <- sample(3:6, 1)
NRows <- sample(2:8, 1)
myMat <- matrix(runif(NCols*NRows), ncol=NCols)
is.square.matrix(myMat)
## functions
makeCacheMatrix <- function(x) {
m <- NULL
set <- function(y) {
x <<- y
m <<- NULL
}
get <- function() x
setInv <- if (is.square.matrix(x) == TRUE) {
function(solve) m <<- solve
}
else {
function(ginv) m <<- ginv
}
getInv <- function() m
list(x, set = set, get = get,
setInv = setInv,
getInv = getInv)
}
cacheSolve <- function(x, ...) {
m <- x$getInv()
if(!is.null(m)) {
message("getting cached data")
return(m)
}
data <- x$get()
m <- if (is.square.matrix(data) == TRUE) {
solve(data, ...)
}
else {
ginv(data, ...)
}
x$setInv(m)
m
}
## run functions for myMat
notSquare <- makeCacheMatrix(myMat)
cacheSolve(notSquare)
##check
ginv(myMat)
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.