Print Specific Output from multiple functions in R - r

I have multiple user defined functions written in R. I usually source the code and then print the output in R console. My problem is I have 3 function written in one file and all three functions have similar output( here I have z which is common in all three function).. Is there any solution in R where I do not have to type print(z) at the end of every function but after sourcing my code I should be able to print z specific to function?
harry<-function(i){
for(i in 3:5) {
z <- i + 1
print(z)
}
}
harry1<-function(i){
for(i in 1:5) {
z <- i + 1
print(z)
}
}
harry2<-function(i){
for(i in 1:5) {
z <- i + 5
print(z)
}
}

harry <- function(i){
z <- 1 # initialize
for(i in 3:5) {
z[i] <- i + 1 # save to vector
}
return(z) # returns the object z
}
Now you can go:
harry(100)
z <- harry(100)
print(z)
z
To access the same information.

Might I suggest a more general way of doing things?
harry<-function(i,sq){
sapply(sq, function(s,i) {
s + i
}, i=i )
}
harry(i=1,sq=3:5)
harry(i=1,sq=1:5)
harry(i=5,sq=1:5)

Related

How to print one result from function but store others

Consider this made up function:
Made_up <- function(x) {
one <- x
two <- x + 1
three <- x + 2
}
How can I have the function only print the result of the object three and store the other variables to be called when I write
answer <- Made_up(1)
answer$....
Similar to Vasily A's answer, you could use return and store the results from the function in answer.
Made_up <- function(x) {
one <- x
two <- x + 1
three <- x + 2
print(three)
return(list(one=one, two=two, three=three))
}
answer <- Made_up(1)
answer$one
[1] 1
how about this:
Made_up <- function(x) {
one <- x
two <- x + 1
three <- x + 2
print(three)
invisible(list(one=one, two=two, three=three))
}

Incrementing i when assigning functions?

I'm trying to create functions containing i in a loop, but i isn't been evaluated.
For example, the loop:
func <- list(0)
for (i in 1:3) {
func[[i]] <- function(x) i*x
}
produces:
> func[[1]]
function(x) i * x
<bytecode: 0x0000000011316b08>
when I actually need 1 * x, 2 * x, 3 * x
Write a function that returns a function. Be sure to use force() to force the evaluation of the lazy parameter.
func <- list(0)
makefun <- function(i) {
force(i)
function(x) i*x
}
func <- Map(makefun, 1:3)
func[[1]](5)
# [1] 5
func[[2]](5)
# [1] 10
func[[3]](5)
# [1] 15
You could do this in a for loop with the help of local().
func <- list(0)
for (i in 1:3) {
func[[i]] <- local({i<-i; function(x) i*x})
}
In both cases the definition still looks like "function(x) i*x" but the environment where the i value is coming from is different.
The issue is that your function refers to i, but there's only one i.MrFlick's answer is one way to force a local environment to be created to hold different copies of i with different values; another is to use local(), e.g.
func <- list()
for (i in 1:3) {
func[[i]] <- local(
{
j <- i # make a local copy of the current value
function(x) j*x
} )
}
func[[1]](5)
# [1] 5
func[[2]](5)
# [1] 10
func[[3]](5)
# [1] 15

Using If trying to get a vector a certain length

I'm trying to use if function to create a vector X that follows the pattern of the if statement, that is length 5. However, when I print X, I get 5 vectors with length 1. How do I fix this
for (i in 1:5) {
if (i <2){
a<-i
}
else {
a<-(i-1)
}
X<-a
print(X)
}
R overwrites the contents of your variables a and X with each loop. To avoid this, you can make X a list, and put your value in a different position with each loop.
X <- list()
a <- list()
for(i in 1:5) {
if(i<2){
a <- i
} else {
a <- i-1
}
X[i] <- a
}
Since your final plan is to create a vector, you may initialize a vector ("X") first, and then add a value ("a") in each 'for' loop.
X = vector("numeric",0)
for (i in 1:5){
if (i<2){
a <- i
}
else{
a <- (i-1)
}
X = c(X, a)
print(X)
}
X
# [1] 1 1 2 3 4

breaking out of for loop when running a function inside a for loop in R

Suppose you have the following function foo. When I'm running a for loop, I'd like it to skip the remainder of foo when foo initially returns the value of 0. However, break doesn't work when it's inside a function.
As it's currently written, I get an error message, no loop to break from, jumping to top level.
Any suggestions?
foo <- function(x) {
y <- x-2
if (y==0) {break} # how do I tell the for loop to skip this
z <- y + 100
z
}
for (i in 1:3) {
print(foo(i))
}
Admittedly my R knowledge is sparse and this is drycoded, but something like the following should work:
foo <- function(x) {
y <- x-2
if (y==0) {return(NULL)} # return NULL then check for it
z <- y + 100
z
}
for (i in 1:3) {
j <- foo(i)
if(is.null(j)) {break}
print(j)
}
Edit: updated null check for posterity
As a matter of coding practice, don't do this. Having a function that can only be used inside a particular loop is not a great idea. As a matter of educational interest, you can evaluate the 'break' in the parent environment.
foo <- function(x) {
y <- x-2
if (y==0) {eval.parent(parse(text="break"),1)}
z <- y + 100
z
}
for (i in 0:3) {
print(foo(i))
}
Are we allowed to be a little more creative? Could you recast your problem to take advantage of the following approach, where the operation is based on vectors?
x <- 1:3
y <- x[x-2 < 0] - 2 + 100 # I'm leaving the "- 2" separate to highlight the parallel to your code
y
If, however, a deeper form underlies the question and we need to follow this pattern for now, perhaps tweak it just a bit...
foo <- function(x) {
y <- x - 2
if (y != 0) {
z <- y + 100
z
} # else implicitly return value is NULL
}
for (i in 1:3) {
if (is.numeric(result <- foo(i))) {
print(result)
} else {
break
}
}
An alternative way is to throw an error and catch it with try, like so:
foo <- function(x) {
y <- x-2
if (y==0) {stop("y==0")}
z <- y + 100
z
}
try(for (i in 0:5) {
print(foo(i))
}, silent=TRUE)
## or use tryCatch:
for (i in 0:5) {
bar <- tryCatch(foo(i),error=function(e) NA)
if(is.na(bar)){ break } else { print(bar) }
}
I have no clue how r works but I found the question interesting because I could lookup a new language's syntax so excuse my answer if it is totally wrong :)
foo <- function(x) {
y <- x-2
if (y!=0) z <- NULL else z <- y + 100
z
}
for (i in 1:3)
{
a <- foo(i)
if (a == NULL) {next}
print(a)
}

Static Variables in R

I have a function in R that I call multiple times. I want to keep track of the number of times that I've called it and use that to make decisions on what to do inside of the function. Here's what I have right now:
f = function( x ) {
count <<- count + 1
return( mean(x) )
}
count = 1
numbers = rnorm( n = 100, mean = 0, sd = 1 )
for ( x in seq(1,100) ) {
mean = f( numbers )
print( count )
}
I don't like that I have to declare the variable count outside the scope of the function. In C or C++ I could just make a static variable. Can I do a similar thing in the R programming language?
Here's one way by using a closure (in the programming language sense), i.e. store the count variable in an enclosing environment accessible only by your function:
make.f <- function() {
count <- 0
f <- function(x) {
count <<- count + 1
return( list(mean=mean(x), count=count) )
}
return( f )
}
f1 <- make.f()
result <- f1(1:10)
print(result$count, result$mean)
result <- f1(1:10)
print(result$count, result$mean)
f2 <- make.f()
result <- f2(1:10)
print(result$count, result$mean)
result <- f2(1:10)
print(result$count, result$mean)
Here is another approach. This one requires less typing and (in my opinion) more readable:
f <- function(x) {
y <- attr(f, "sum")
if (is.null(y)) {
y <- 0
}
y <- x + y
attr(f, "sum") <<- y
return(y)
}
This snippet, as well as more complex example of the concept can by found in this R-Bloggers article
It seems the right answer was given by G. Grothendieck there: Emulating static variable within R functions But somehow this post got more favorable position in google search, so i copy this answer here:
Define f within a local like this:
f <- local({
static <- 0
function() { static <<- static + 1; static }
})
f()
## [1] 1
f()
## [1] 2

Resources