I'm trying to write a function in R that will return as its output, an one output from a previous function. The previous function returns a list of 3 different things.
So far the only way I've worked out how to do this is completely copy and paste the original function, and get it to return only one answer, but surely there is a shorter way in which to do this?
If the original function is named foo(), as in
foo <- function ( something ) {
# some code
return(list(residuals, residualssquared,tss))
}
then just do
bar <- function ( something ) {
return ( foo(something)$tss )
}
or simply use foo(something)$tss to directly access the tss component of the return value of foo(). There is really no need to wrap another function bar() around foo().
Related
Goal
I am trying to create a function in R to replicate the functionality of a homonymous MATLAB function which returns the number of arguments that were passed to a function.
Example
Consider the function below:
addme <- function(a, b) {
if (nargin() == 2) {
c <- a + b
} else if (nargin() == 1) {
c <- a + a
} else {
c <- 0
}
return(c)
}
Once the user runs addme(), I want nargin() to basically look at how many parameters were passed―2 (a and b), only 1 (a) or none―and calculate c accordingly.
What I have tried
After spending a lot of time messing around with environments, this is the closest I ever got to a working solution:
nargin <- function() {
length(as.list(match.call(envir = parent.env(environment()))))
}
The problem with this function is that it always returns 0, and the reason why is that I think it's looking at its own environment instead of its parent's (in spite of my attempt of throwing in a parent.env there).
I know I can use missing() and args() inside addme() to achieve the same functionality, but I'll be needing this quite a few other times throughout my project, so wrapping it in a function is definitely something I should try to do.
Question
How can I get nargin() to return the number of arguments that were passed to its parent function?
You could use
nargin <- function() {
if(sys.nframe()<2) stop("must be called from inside a function")
length(as.list(sys.call(-1)))-1
}
Basically you just use sys.call(-1) to go up the call stack to the calling function and get it's call and then count the number of elements and subtract one for the function name itself.
I need help on returning a value/object from function
noReturnKeyword <- function(){
'noReturnKeyword'
}
justReturnValue <- function(){
returnValue('returnValue')
}
justReturn <- function(){
return('justReturn')
}
When I invoked these functions: noReturnKeyword(), justReturnValue(), justReturn(), I got output as [1] "noReturnKeyword", [1] "returnValue", [1] "justReturn" respectively.
My question is, even though I have not used returnValue or return keywords explicitly in noReturnKeyword() I got the output (I mean the value returned by the function).
So what is the difference in these function noReturnKeyword(), justReturnValue(), justReturn()
What is the difference in these words returnValue('') , return('')? are these one and the same?
When to go for returnValue('') and return('') in R functions ?
In R, according to ?return
If the end of a function is reached without calling return, the value of the last evaluated expression is returned.
return is the explicite way to exit a function and set the value that shall be returned. The advantage is that you can use it anywhere in your function.
If there is no explicit return statement R will return the value of the last evaluated expression
returnValueis only defined in a debugging context. The manual states:
the experimental returnValue() function may be called to obtain the
value about to be returned by the function. Calling this function in
other circumstances will give undefined results.
In other words, you shouldn't use that except in the context of on.exit. It does not even work when you try this.
justReturnValue <- function(){
returnValue('returnValue')
2
}
This function will return 2, not "returnValue". What happened in your example is nothing more than the second approach. R evaluates the last statement which is returnValue() and returns exactly that.
If you use solution 1 or 2 is up to you. I personally prefer the explicit way because I believe it makes the code clearer. But that is more a matter of opinion.
my question is: how to move to the next loop in PARI/GP if I use multi-line nested for loops ? for example :
if I use this code :
for(K=1,10,for(i=1,5,if(isprime(2*i*prime(K)+1)==1,print(2*i"*"prime(K)))))
and since 2*(i=1)*prime(K=1)+1=5 is prime, I need my machine not to loop for i=2......i=5, I need it to move on to the next K, so:
how to do this on PARI/GP?
and I am sorry if my question is not clear or duplicated.
You need to use break. But first, let's clean up the presentation so this is more readable:
func()=
{
for(K=1,10,
for(i=1,5,
if(isprime(2*i*prime(K)+1)==1,
print(2*i"*"prime(K))
)
)
);
}
func()
You want to break out of the innermost loop, like so (just giving the function itself):
func()=
{
for(K=1,10,
for(i=1,5,
if(isprime(2*i*prime(K)+1)==1,
print(2*i"*"prime(K));
break
)
)
);
}
But while we're here, there's no need to add == 1; if is already branching on nonzero values.
func()=
{
for(K=1,10,
for(i=1,5,
if(isprime(2*i*prime(K)+1),
print(2*i"*"prime(K));
break
)
)
);
}
We could also store the value of prime(K) so we don't need to compute it twice. But better yet, let's use a loop directly over the primes so we don't need the prime() function at all!
func(maxK=10)=
{
my(K=0);
forprime(p=2,prime(maxK),
K++;
for(i=1,5,
if(isprime(2*i*p+1),
print(2*i"*"p);
break
)
)
);
}
Here I have changed the function so you can call it with different maximum values other than 10 and I've kept the index in case you wanted it for some reason. But I think a better approach would be to give a bound on how high you want to go in the primes directly, and forgetting about the prime indexes entirely:
func(maxP=29)=
{
forprime(p=2,maxP,
for(i=1,5,
if(isprime(2*i*p+1),
print(2*i"*"p);
break
)
)
);
}
In both cases I added a default argument so calling func() will do the same thing as your original function (except that it now breaks the way you want).
This question is only for curiosity. My colleague and I were trying to write a function which returns NULL, but doesn't print it.
Before we found return(invisible(NULL)), I tried return({dummy<-NULL}) which works, but only once. After the first evaluation, the functions starts printing again:
test <- function() {
return({x<-NULL})
}
# no printout
test()
# with printout
test()
# with printout
test()
How does this come about?
I think this is due to some older return handling built into R. There are many return functions, withVisible, invisible, etc. When you return an assignment x<-null inside the return function it will not automatically print. If you want an assignment to print...
test <- function() {
withAutoprint(x<-NULL)
}
# with printout this time
test()
# with printout
test()
# with printout
test()
I think this just may be hard coded into the return function, maybe pulling something from this logic below, just a shot in the dark though.
Source: R Documentation
x <- 1
withVisible(x <- 1) # *$visible is FALSE
x
withVisible(x) # *$visible is TRUE
Again if we do not use an expression and simply return a variable or value inside our return function we get automatic printing. The reason I am guessing it returns on a second call has to do with the fact x was already assigned previously.
EDIT: I found this deep into the documentation on auto printing. "Whether the returned value of a top-level R expression is printed is controlled by the global boolean variable R_Visible. This is set (to true or false) on entry to all primitive and internal functions based on the eval column of the table in file src/main/names.c: the appropriate setting can be extracted by the macro PRIMPRINT."(Source)
I'm trying to figure out how to get R's callCC function for short-circuiting evalutation of a function to work with functions like lapply and Reduce.
Motivation
This would make Reduce and and lapply have asymptotic efficiency > O(n), by allowing you to
exit a computation early.
For example, if I'm searching for a value in a list I could map a 'finder' function across the list, and the second it is found lapply stops running and that value is returned (much like breaking a loop, or using a return statement to break out early).
The problem is I am having trouble writing the functions that lapply and Reduce should take using a style that callCC requires.
Example
Say I'm trying to write a function to find the value '100' in a list: something equivalent to
imperativeVersion <- function (xs) {
for (val in xs) if (val == 100) return (val)
}
The function to pass to lapply would look like:
find100 <- function (val) { if (val == 100) SHORT_CIRCUIT(val) }
functionalVersion <- function (xs) lapply(xs, find100)
This (obviously) crashes, since the short circuiting function hasn't been defined yet.
callCC( function (SHORT_CIRCUIT) lapply(1:1000, find100) )
The problem is that this also crashes, because the short circuiting function wasn't around when find100 was defined. I would like for something similar to this to work.
the following works because SHORT_CIRCUIT IS defined at the time that the function passed to lapply is created.
callCC(
function (SHORT_CIRCUIT) {
lapply(1:1000, function (val) {
if (val == 100) SHORT_CIRCUIT(val)
})
)
How can I make SHORT_CIRCUIT be defined in the function passed to lapply without defining it inline like above?
I'm aware this example can be achieved using loops, reduce or any other number of ways. I am looking for a solution to the problem of using callCC with lapply and Reduce in specific.
If I was vague or any clarification is needed please leave a comment below. I hope someone can help with this :)
Edit One:
The approach should be 'production-quality'; no deparsing functions or similar black magic.
I found a soluton to this problem:
find100 <- function (val) {
if (val == 100) SHORT_CIRCUIT(val)
}
short_map <- function (fn, coll) {
callCC(function (SHORT_CIRCUIT) {
clone_env <- new.env(parent = environment(fn))
clone_env$SHORT_CIRCUIT <- SHORT_CIRCUIT
environment(fn) <- clone_env
lapply(coll, fn)
})
}
short_map(find100, c(1,2,100,3))
The trick to making higher-order functions work with callCC is to assign the short-circuiting function into the input functions environment before carrying on with the rest of the program. I made a clone of the environment to avoid unintended side-effects.
You can achieve this using metaprogramming in R.
#alexis_laz's approach was in fact already metaprogramming.
However, he used strings which are a dirty hack and error prone. So you did well to reject it.
The correct way to approach #alexis_laz's approach would be by wrangling on code level. In base R this is done using substitute(). There are however better packages e.g. rlang by Hadley Wickham. But I give you a base R solution (less dependency).
lapply_ <- function(lst, FUN) {
eval.parent(
substitute(
callCC(function(return_) {
lapply(lst_, FUN_)
}),
list(lst_ = lst, FUN_=substitute(FUN))))
}
Your SHORT_CIRCUIT function is actually a more general, control flow return function (or a break function which takes an argument to return it). Thus, I call it return_.
We want to have a lapply_ function, in which we can in the FUN= part use a return_ to break out of the usual lapply().
As you showed, this is the aim:
callCC(
function (return_) {
lapply(1:1000, function (x) if (x == 100) return_(x))
}
)
Just with the problem, that we want to be able to generalize this expression.
We want
callCC(
function(return_) lapply(lst, FUN_)
)
Where we can use inside the function definition we give for FUN_ the return_.
We can let, however, the function defintion see return_ only if we insert the function definition code into this expression.
This exactly #alexis_laz tried using string and eval.
Or you did this by manipulating environment variables.
We can safely achieve the insertion of literal code using substitute(expr, replacer_list) where expr is the code to be manipulated and replacer_list is the lookup table for the replacement of code.
By substitute(FUN) we take the literal code given for FUN= for lapply_ without evaluating it. This expression returns literal quoted code (better than the string in #alexis_laz's approach).
The big substitute command says: "Take the expression callCC(function(return_) lapply(lst_, FUN_)) and replace lst_ in this expression by the list given for coll and FUN_ by the literal quoted expression given for FUN.
This replaced expression is then evaluated in the parent environment (eval.parent()) meaning: the resulting expression replaces the lapply_() call and is executed exactly where it was placed.
Such use of eval.parent() (or eval( ... , envir=parent.frame())) is fool proof. (otherwise, tidyverse packages wouldn't be production level ...).
So in this way, you can generalize callCC() calls.
lapply_(1:1000, FUN=function(x) if (x==100) return_(x))
## [1] 100
I don't know if it can be of use, but:
find100 <- "function (val) { if (val == 100) SHORT_CIRCUIT(val) }"
callCC( function (SHORT_CIRCUIT) lapply(1:1000, eval(parse(text = find100))) )
#[1] 100