R: Passing parameters from a wrapper function to internal functions - r

I am not surprised that this function doesn't work, but I cannot quite understand why.
computeMeans <- function(data,dv,fun) {
x <- with(data,aggregate(dv,
list(
method=method,
hypo=hypothesis,
pre.group=pre.group,
pre.smooth=pre.smooth
),
fun ) )
return(x)
}
computeMeans(df.basic,dprime,mean)
Where df.basic is a dataframe with factors method, hypothesis, etc, and several dependent variables (and I specify one with the dv parameter, dprime).
I have multiple dependent variables and several dataframes all of the same form, so I wanted to write this little function to keep things "simple". The error I get is:
Error in aggregate(dv, list(method = method, hypo = hypothesis,
pre.group = pre.group, :
object 'dprime' not found
But dprime does exist in df.basic, which is referenced with with(). Can anyone explain the problem? Thank you!
EDIT: This is the R programming language. http://www.r-project.org/

Although dprime exists in df.basic, when you call it at computeMeans it has no idea what you are referring to, unless you explicitly reference it.
computeMeans(df.basic,df.basic$dprime,mean)
will work.

Alternatively
computeMeans <- function(data,dv,fun) {
dv <- eval(substitute(dv), envir=data)
x <- with(data,aggregate(dv,
list(
method=method,
hypo=hypothesis,
pre.group=pre.group,
pre.smooth=pre.smooth
),
fun ) )
return(x)
}
You might think that since dv is in the with(data, (.)) call, it gets evaluated within the environment of data. It does not.
When a function is called the arguments are matched and then each of
the formal arguments is bound to a promise. The expression that was
given for that formal argument and a pointer to the environment the
function was called from are stored in the promise.
Until that argument is accessed there is no value associated with the
promise. When the argument is accessed, the stored expression is
evaluated in the stored environment, and the result is returned. The
result is also saved by the promise.
source
A promise is therefore evaluated within the environment in which it was created (ie, the environment where the function was called), regardless of the environment in which the promise is first called. Observe:
delayedAssign("x", y)
local({
y <- 10
x
})
Error in eval(expr, envir, enclos) : object 'y' not found
w <- 10
delayedAssign("z", w)
local({
w <- 11
z
})
[1] 10
Note that delayedAssign creates a promise. In the first example, x is assigned the value of y via a promise in the global environemnt, but y has not been defined in the global enviornment. x is called in an enviornment where y has been defined, yet calling x still results in an error indicating that y does not exist. This demonstrates that x is evaluated in environment in which the promise was defined, not in its current environment.
In the second example, z is assigned the value of w via a promise in the global environment, and w is defined in the global environment. z is then called in an enviornment where w has been assigned a different value, yet z still returns the value of the w in the environment where the promise has been created.

Passing in the dprime argument as a character string would allow you to sidestep any consideration of the involved scoping and evaluation rules discussed in #Michael's answer:
computeMeans <- function(data, dv, fun) {
x <- aggregate(data[[dv]],
list(
method = data[["method"]],
hypo = data[["hypothesis"]],
pre.group = data[["pre.group"]],
pre.smooth = data[["pre.smooth"]]
),
fun )
return(x)
}
computeMeans(df.basic, "dprime", mean)

Related

Why does my R function have knowledge of variables that are not given as arguments? [duplicate]

Is there any way to throw a warning (and fail..) if a global variable is used within a R function? I think that is much saver and prevents unintended behaviours...e.g.
sUm <- 10
sum <- function(x,y){
sum = x+y
return(sUm)
}
due to the "typo" in return the function will always return 10. Instead of returning the value of sUm it should fail.
My other answer is more about what approach you can take inside your function. Now I'll provide some insight on what to do once your function is defined.
To ensure that your function is not using global variables when it shouldn't be, use the codetools package.
library(codetools)
sUm <- 10
f <- function(x, y) {
sum = x + y
return(sUm)
}
checkUsage(f)
This will print the message:
<anonymous> local variable ‘sum’ assigned but may not be used (:1)
To see if any global variables were used in your function, you can compare the output of the findGlobals() function with the variables in the global environment.
> findGlobals(f)
[1] "{" "+" "=" "return" "sUm"
> intersect(findGlobals(f), ls(envir=.GlobalEnv))
[1] "sUm"
That tells you that the global variable sUm was used inside f() when it probably shouldn't have been.
There is no way to permanently change how variables are resolved because that would break a lot of functions. The behavior you don't like is actually very useful in many cases.
If a variable is not found in a function, R will check the environment where the function was defined for such a variable. You can change this environment with the environment() function. For example
environment(sum) <- baseenv()
sum(4,5)
# Error in sum(4, 5) : object 'sUm' not found
This works because baseenv() points to the "base" environment which is empty. However, note that you don't have access to other functions with this method
myfun<-function(x,y) {x+y}
sum <- function(x,y){sum = myfun(x+y); return(sUm)}
environment(sum)<-baseenv()
sum(4,5)
# Error in sum(4, 5) : could not find function "myfun"
because in a functional language such as R, functions are just regular variables that are also scoped in the environment in which they are defined and would not be available in the base environment.
You would manually have to change the environment for each function you write. Again, there is no way to change this default behavior because many of the base R functions and functions defined in packages rely on this behavior.
Using get is a way:
sUm <- 10
sum <- function(x,y){
sum <- x+y
#with inherits = FALSE below the variable is only searched
#in the specified environment in the envir argument below
get('sUm', envir = environment(), inherits=FALSE)
}
Output:
> sum(1,6)
Error in get("sUm", envir = environment(), inherits = FALSE) :
object 'sUm' not found
Having the right sum in the get function would still only look inside the function's environment for the variable, meaning that if there were two variables, one inside the function and one in the global environment with the same name, the function would always look for the variable inside the function's environment and never at the global environment:
sum <- 10
sum2 <- function(x,y){
sum <- x+y
get('sum', envir = environment(), inherits=FALSE)
}
> sum2(1,7)
[1] 8
You can check whether the variable's name appears in the list of global variables. Note that this is imperfect if the global variable in question has the same name as an argument to your function.
if (deparse(substitute(var)) %in% ls(envir=.GlobalEnv))
stop("Do not use a global variable!")
The stop() function will halt execution of the function and display the given error message.
Another way (or style) is to keep all global variables in a special environment:
with( globals <- new.env(), {
# here define all "global variables"
sUm <- 10
mEan <- 5
})
# or add a variable by using $
globals$another_one <- 42
Then the function won't be able to get them:
sum <- function(x,y){
sum = x+y
return(sUm)
}
sum(1,2)
# Error in sum(1, 2) : object 'sUm' not found
But you can always use them with globals$:
globals$sUm
[1] 10
To manage the discipline, you can check if there is any global variable (except functions) outside of globals:
setdiff(ls(), union(lsf.str(), "globals")))

Understanding evaluation of input arguments of functions

I am reading Advanced R by Hadley Wickham where some very good exercises are provided. One of them asks for description of this function:
f1 <- function(x = {y <- 1; 2}, y = 0) {
x + y
}
f1()
Can someone help me to understand why it returns 3? I know there is something called lazy evaluation of the input arguments, and e.g. another exercise asks for description of this function
f2 <- function(x = z) {
z <- 100
x
}
f2()
and I correctly predicted to be 100; x gets value of z which is evaluated inside a function, and then x is returned. I cannot figure out what happens in f1(), though.
Thanks.
See this from https://cran.r-project.org/doc/manuals/r-patched/R-lang.html#Evaluation:
When a function is called or invoked a new evaluation frame is
created. In this frame the formal arguments are matched with the
supplied arguments according to the rules given in Argument matching.
The statements in the body of the function are evaluated sequentially
in this environment frame.
...
R has a form of lazy evaluation of function arguments. Arguments are not evaluated until needed.
and this from https://cran.r-project.org/doc/manuals/r-patched/R-lang.html#Arguments:
Default values for arguments can be specified using the special form
‘name = expression’. In this case, if the user does not specify a
value for the argument when the function is invoked the expression
will be associated with the corresponding symbol. When a value is
needed the expression is evaluated in the evaluation frame of the
function.
In summary, if the parameter does not have user-specified value, its default value will be evaluated in the function's evaluation frame. So y is not evalulated at first. When the default of x is evaluated in the function's evaluation frame, y will be modified to 1, then x will be set to 2. As y is already found, the default argument has no change to be evaluated. if you try f1(y = 1) and f1(y = 2), the results are still 3.

Strange behavior in default argument enclos =parent.frame() of eval function

I'm currently having some issues understanding the behavior of the eval function- specifically the enclos/third argument when an argument isn't supplied to it/ the default argument parent.fame() is used.
name <- function(x){
print(substitute(x))
t <- substitute(x)
eval(t, list(a=7), parent.frame())
}
z <-5
name(a+z)
# returns 12, makes sense because this amounts to
# eval(a+z, list(a=7), glovalenv())
# however the return here makes no sense to me
name2 <- function(x){
print(substitute(x))
t <- substitute(x)
eval(t, list(a=7)) # third/enclosure argument is left missing
}
z <-5
name2(a+z)
# Also returns 12
I'm having trouble understanding why the second call returns 12. According to my understanding of R, the second call should result in an error because
1) eval's default third argument enclos= parent.frame(), which is not specified.
2) Therefore, parent.frame() is evaluated in the local environment of eval. This is confirmed by Hadley in When/how/where is parent.frame in a default argument interpreted?
3) Thus, the last expression ought to resolve to eval(a+z, list(a=7), executing environment of name)
4) This should return an error because z is not defined in the executing environment of name nor in list(a=7).
Can someone please explain what's wrong with this logic?
z will be available inside the function since it's defined in .GlobalEnv.
Simply put,
name <- function(x) {
print(z)
}
z <- 5
name(z)
# [1] 5
So while a is still unknown until eval(t, list(a=7)), z is already available. If z is not defined inside name, it will be looked for in .GlobalEnv. What might be counterintuitive is that (a+z) is undefined unless you specify an environment for a. But for z, there is no need to do so.

R scoping: disallow global variables in function

Is there any way to throw a warning (and fail..) if a global variable is used within a R function? I think that is much saver and prevents unintended behaviours...e.g.
sUm <- 10
sum <- function(x,y){
sum = x+y
return(sUm)
}
due to the "typo" in return the function will always return 10. Instead of returning the value of sUm it should fail.
My other answer is more about what approach you can take inside your function. Now I'll provide some insight on what to do once your function is defined.
To ensure that your function is not using global variables when it shouldn't be, use the codetools package.
library(codetools)
sUm <- 10
f <- function(x, y) {
sum = x + y
return(sUm)
}
checkUsage(f)
This will print the message:
<anonymous> local variable ‘sum’ assigned but may not be used (:1)
To see if any global variables were used in your function, you can compare the output of the findGlobals() function with the variables in the global environment.
> findGlobals(f)
[1] "{" "+" "=" "return" "sUm"
> intersect(findGlobals(f), ls(envir=.GlobalEnv))
[1] "sUm"
That tells you that the global variable sUm was used inside f() when it probably shouldn't have been.
There is no way to permanently change how variables are resolved because that would break a lot of functions. The behavior you don't like is actually very useful in many cases.
If a variable is not found in a function, R will check the environment where the function was defined for such a variable. You can change this environment with the environment() function. For example
environment(sum) <- baseenv()
sum(4,5)
# Error in sum(4, 5) : object 'sUm' not found
This works because baseenv() points to the "base" environment which is empty. However, note that you don't have access to other functions with this method
myfun<-function(x,y) {x+y}
sum <- function(x,y){sum = myfun(x+y); return(sUm)}
environment(sum)<-baseenv()
sum(4,5)
# Error in sum(4, 5) : could not find function "myfun"
because in a functional language such as R, functions are just regular variables that are also scoped in the environment in which they are defined and would not be available in the base environment.
You would manually have to change the environment for each function you write. Again, there is no way to change this default behavior because many of the base R functions and functions defined in packages rely on this behavior.
Using get is a way:
sUm <- 10
sum <- function(x,y){
sum <- x+y
#with inherits = FALSE below the variable is only searched
#in the specified environment in the envir argument below
get('sUm', envir = environment(), inherits=FALSE)
}
Output:
> sum(1,6)
Error in get("sUm", envir = environment(), inherits = FALSE) :
object 'sUm' not found
Having the right sum in the get function would still only look inside the function's environment for the variable, meaning that if there were two variables, one inside the function and one in the global environment with the same name, the function would always look for the variable inside the function's environment and never at the global environment:
sum <- 10
sum2 <- function(x,y){
sum <- x+y
get('sum', envir = environment(), inherits=FALSE)
}
> sum2(1,7)
[1] 8
You can check whether the variable's name appears in the list of global variables. Note that this is imperfect if the global variable in question has the same name as an argument to your function.
if (deparse(substitute(var)) %in% ls(envir=.GlobalEnv))
stop("Do not use a global variable!")
The stop() function will halt execution of the function and display the given error message.
Another way (or style) is to keep all global variables in a special environment:
with( globals <- new.env(), {
# here define all "global variables"
sUm <- 10
mEan <- 5
})
# or add a variable by using $
globals$another_one <- 42
Then the function won't be able to get them:
sum <- function(x,y){
sum = x+y
return(sUm)
}
sum(1,2)
# Error in sum(1, 2) : object 'sUm' not found
But you can always use them with globals$:
globals$sUm
[1] 10
To manage the discipline, you can check if there is any global variable (except functions) outside of globals:
setdiff(ls(), union(lsf.str(), "globals")))

Caching the mean of a Vector in R

I am learning R and came across some code as part of the practice assignment.
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)
}
The documentation says:
The function, makeVector creates a special "vector", which is
really a list containing a function to
set the value of the vector
get the value of the vector
set the value of the mean
get the value of the mean
But i can not understand how the function works except for the point that it is assigning mean value to the variable m in that particular environment.
m <- NULL begins by setting the mean to NULL as a placeholder for a future value
set <- function(y) {x <<- y; m <<- NULL} defines a function to set the vector, x, to a new
vector, y, and resets the mean, m, to NULL
get <- function() x returns the vector, x
setmean <- function(mean) m <<- mean sets the mean, m, to mean
getmean <- function() m returns the mean, m
list(set = set, get = get,setmean = setmean,getmean = getmean) returns the 'special
vector' containing all of the functions just defined
This answer is an excerpt from an article I originally wrote in 2016 as a Community Mentor in the Johns Hopkins University R Programming course: Demystifying makeVector().
Overall Design of makeVector() and cachemean()
The cachemean.R file contains two functions, makeVector() and cachemean(). The first function in the file, makeVector() creates an R object that stores a vector and its mean. The second function, cachemean() requires an argument that is returned by makeVector() in order to retrieve the mean from the cached value that is stored in the makeVector() object's environment.
What's going on in makeVector()?
The key concept to understand in makeVector() is that it builds a set of functions and returns the functions within a list to the parent environment. That is,
myVector <- makeVector(1:15)
results in an object, myVector, that contains four functions: set(), get(), setmean(), and getmean(). It also includes the two data objects, x and m.
Due to lexical scoping, myVector contains a complete copy of the environment for makeVector(), including any objects that are defined within makeVector() at design time (i.e., when it was coded). A diagram of the environment hierarchy makes it clear what is accessible within myVector.
Illustrated as a hierarchy, the global environment contains the makeVector() environment. All other content is present in the makeVector() environment, as illustrated below.
Since each function has its own environment in R, the hierarchy illustrates that the objects x and m are siblings of the four functions, get(), set(), getmean(), and setmean().
Once the function is run and an object of type makeVector() is instantiated (that is, created), the environment containing myVector looks like:
Notice that the object x contains the vector 1:15, even though myVector$set() has not been executed. This is the case because the value 1:15 was passed as an argument into the makeVector() function. What explains this behavior?
When an R function returns an object that contains functions to its parent environment (as is the case with a call like myVector <- makeVector(1:15)), not only does myVector have access to the specific functions in its list, but it also retains access to the entire environment defined by makeVector(), including the original argument used to start the function.
Why is this the case? myVector contains pointers to functions that are within the makeVector() environment after the function ends, so these pointers prevent the memory consumed by makeVector() from being released by the garbage collector. Therefore, the entire makeVector() environment stays in memory, and myVector can access its functions as well as any data in that environment that is referenced in its functions.
This feature explains why x (the argument initialized on the original function call) is accessible by subsequent calls to functions on myVector such as myVector$get(), and it also explains why the code works without having to explicitly issue myVector$set() to set the value of x.
makeVector() step by step
Now, let's break the behavior of the function down, step by step.
Step 1: Initialize objects
The first thing that occurs in the function is the initialization of two objects, x and m.
makeVector(x = numeric()) {
m <- NULL
...
}
Notice that x is initialized as a function argument, so no further initialization is required within the function. m is set to NULL, initializing it as an object within the makeVector() environment to be used by later code in the function.
Furthermore, the formals part of the function declaration define the default value of x as an empty numeric vector. Initialization of the vector with a default value is important because without a default value, data <- x$get() generates the following error message.
Error in x$get() : argument "x" is missing, with no default
Step 2: Define the "behaviors" or functions for objects of type makeVector()
After initializing key objects that store key information within makeVector(), the code provides four basic behaviors that are typical for data elements within an object-oriented program. They're called "getters and settters," and more formally known as mutator and accessor methods. As one might expect, "getters" are program modules that retrieve (access) data within an object, and "setters" are program modules that set (mutate) the data values within an object.
First makeVector() defines the set() function. Most of the "magic" in makeVector() takes place in the set() function.
set <- function(y) {
x <<- y
m <<- NULL
}
set() takes an argument that is named as y. It is assumed that this value is a numeric vector, but is not stated directly in the function formals. For the purposes of the set() function, it doesn't matter whether this argument is called y, aVector or any object name other than x. Why? Since there is an x object already defined in the makeVector() environment, using the same object name would make the code more difficult to understand.
Within set() we use the <<- form of the assignment operator, which assigns the value on the right side of the operator to an object in the parent environment named by the object on the left side of the operator.
When set() is executed, it does two things:
Assign the input argument to the x object in the parent environment, and
Assign the value of NULL to the m object in the parent environment. This line of code clears any value of m that had been cached by a prior execution of cachemean().
Therefore, if there is already a valid mean cached in m, whenever x is reset, the value of m cached in the memory of the object is cleared, forcing subsequent calls to cachemean() to recalculate the mean rather than retrieving the wrong value from cache.
Notice that the two lines of code in set() do exactly the same thing as the first two lines in the main function: set the value of x, and NULL the value of m.
Second, makeVector() defines the getter for the vector x.
get <- function() x
Again, this function takes advantage of the lexical scoping features in R. Since the symbol x is not defined within get(), R retrieves it from the parent environment of makeVector().
Third, makeVector() defines the setter for the mean m.
setmean <- function(mean) m <<- mean
Since m is defined in the parent environment and we need to access it after setmean() completes, the code uses the <<- form of the assignment operator to assign the input argument to the value of m in the parent environment.
Finally, makeVector() defines the getter for the mean m. Just like the getter for x, R takes advantage of lexical scoping to find the correct symbol m to retrieve its value.
getmean <- function() m
At this point we have getters and setters defined for both of the data objects within our makeVector() object.
Step 3: Create a new object by returning a list()
Here is the other part of the "magic" in the operations of the makeVector() function. The last section of code assigns each of these functions as an element within a list(), and returns it to the parent environment.
list(set = set, get = get,
setmean = setmean,
getmean = getmean)
When the function ends, it returns a fully formed object of type makeVector() to be used by downstream R code. One other important subtlety about this code is that each element in the list is named. That is, each element in the list is created with a elementName = value syntax, as follows:
list(set = set, # gives the name 'set' to the set() function defined above
get = get, # gives the name 'get' to the get() function defined above
setmean = setmean, # gives the name 'setmean' to the setmean() function defined above
getmean = getmean) # gives the name 'getmean' to the getmean() function defined above
Naming the list elements is what allows us to use the $ form of the extract operator to access the functions by name rather than using the [[ form of the extract operator, as in myVector[[2]](), to get the contents of the vector.
Here it's important to note that the cachemean() function REQUIRES an input argument of type makeVector(). If one passes a regular vector to the function, as in
aResult <- cachemean(1:15)
the function call will fail with an error explaining that cachemean() was unable to access $getmean() on the input argument because $ does not work with atomic vectors. This is accurate, because a primitive vector is not a list, nor does it contain a $getmean() function, as illustrated below.
> aVector <- 1:10
> cachemean(aVector)
Error in x$getmean : $ operator is invalid for atomic vectors
Explaining cachemean()
Without cachemean(), the makeVector() function is incomplete. Why? As designed, cachemean() is required to populate or retrieve the mean from an object of type makeVector().
cachemean <- function(x, ...) {
...
Like makeVector(), cachemean() starts with a single argument, x, and an ellipsis that allows the caller to pass additional arguments into the function.
Next, the function attempts to retrieve a mean from the object passed in as the argument. First, it calls the getmean() function on the input object.
m <- x$getmean()
Then it checks to see whether the result is NULL. Since makeVector() sets the cached mean to NULL whenever a new vector is set into the object, if the value here is not equal to NULL, we have a valid, cached mean and can return it to the parent environment
if(!is.null(m)) {
message("getting cached data")
return(m)
}
If the result of !is.null(m) is FALSE, cachemean() gets the vector from the input object, calculates a mean(), uses the setmean() function on the input object to set the mean in the input object, and then returns the value of the mean to the parent environment by printing the mean object.
data <- x$get()
m <- mean(data, ...)
x$setmean(m)
m
Note that cachemean() is the only place where the mean() function is executed, which is why makeVector() is incomplete without cachemean().
Putting the Pieces Together: How the functions work at runtime
Now that we've explained the design of each of these functions, here is an illustration of how they work when used in an R script.
aVector <- makeVector(1:10)
aVector$get() # retrieve the value of x
aVector$getmean() # retrieve the value of m, which should be NULL
aVector$set(30:50) # reset value with a new vector
cachemean(aVector) # notice mean calculated is mean of 30:50, not 1:10
aVector$getmean() # retrieve it directly, now that it has been cached
Conclusion: what makes cachemean() work?
To summarize, the lexical scoping assignment in R Programming takes advantage of lexical scoping and the fact that functions that return objects of type list() also allow access to any other objects defined in the environment of the original function. In the specific instance of makeVector() this means that subsequent code can access the values of x or m through the use of getters and setters. This is how cachemean() is able to calculate and store the mean for the input argument if it is of type makeVector(). Because list elements in makeVector() are defined with names, we can access these functions with the $ form of the extract operator.
For additional commentary that explains how the assignment uses features of the S3 object system, please review makeCacheMatrix() as an Object.
Appendix A: What's the Point of this Assignment?
Once students get through the assignment, they frequently ask questions about its value and purpose. A good article explaining the value of lexical scoping in statistical computing is Lexical Scoping and Statistical Computing, written by Robert Gentleman and Ross Ihaka at the University of Auckland.
Appendix B: cachemean.R
Here is the entire listing for cachemean.R.
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
}
Appendix C: Frequently Asked Questions
Q: Why doesn't cachemean() return the cached value? My code looks like:
cachemean(makeVector(1:100))
cachemean(makeVector(1:100))
A: Code written this way creates two different objects of type makeVector(), so the two calls to cachemean() initialize the means of each instance, rather than caching and retrieving from a single instance. Another way of illustrating how the above code operates is as follows.
Notice how the first call to cachemean() sets the cache, and the second call retrieves data from it.
Q: Why is set() never used in the code?
A: set() is included so that once an object of type makeVector() is created, its value can be changed without initializing another instance of the object. It is unnecessary the first time an object of type makeVector() is instantiated. Why? First, the value of x is set as a function argument, as in makeVector(1:30). Then, the first line of code in the function sets m <- NULL, simultaneously allocating memory for m and setting it to NULL. When a reference to this object is passed to the parent environment when the function ends, both x and m are available to be accessed by their respective get and set functions.
The following code illustrates the use of set().
Q: Why is x set with a default value in makeVector()?
A: Since x is an argument, the only place where one can set a default for it is in the formals. The type of error returned by cachemean() when a default value is not set,
Error in x$get() : argument "x" is missing, with no default
is undesirable. Our code should directly handle error conditions rather than relying on the underlying error handling in R.
It's perfectly valid to create an object of type makeVector() without populating its value during initialization. makeVector() includes a setter function so one can set its value after the object is created. However, the object must have valid data, a numeric vector, prior to executing cachemean().
Ideally, cachemean() would include logic to validate that x is not empty prior to calculating a mean. The default setting of x enables cachemean() to return NaN, which is a reasonable result.
References
Chi, Yau -- R-Tutor Named List Members, retrieved July 20, 2016.
Wickham, Hadley -- Advanced-R Functions, retrieved July 17, 2016.
Wickham, Hadley -- Advanced-R Scoping Issues, retrieved July 17, 2016.
I think that one good way to understand this example is trying the follow:
First check that when you use the function make_Vector now you have of four different setting
> mvec <- makeVector()
> x <- 1:4
> mvec$set(x)
> mvec$get()
> [1] 1 2 3 4
> mvec$getmean()
> NULL
> mvec$setmean(3.4)
> mvec$getmean()
> 3.4
3.4 It's not the correct mean, I put these number then you can check that you can set whatever number that you want.
The second part of the assignment is the follow:
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
}
These part or code check if you have the mean of the vector of interest. If these exist then you don't need calculate and you can use the cache variable.

I put a wrong number for the mean, then you can see that already I set the mean value as follow:
> cachemean(mvec)
> 3.4
You must pass the original mvec list used in the example

Resources