0% found this document useful (0 votes)
25 views

Unit 2 R Factorial Functions

This document discusses functions in R, including how to define, call, and return values from functions. Some key points covered include: - Functions are defined using the function() syntax and can take arguments and have bodies that include statements. - Functions can return single values or lists of multiple values. Returned values are assigned to the function call. - R uses lexical scoping rules to evaluate free variables - it looks in the environment where a function is defined rather than where it is called. - Functions create fresh environments each time they are called, so values cannot carry over between calls.

Uploaded by

liman69609
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views

Unit 2 R Factorial Functions

This document discusses functions in R, including how to define, call, and return values from functions. Some key points covered include: - Functions are defined using the function() syntax and can take arguments and have bodies that include statements. - Functions can return single values or lists of multiple values. Returned values are assigned to the function call. - R uses lexical scoping rules to evaluate free variables - it looks in the environment where a function is defined rather than where it is called. - Functions create fresh environments each time they are called, so values cannot carry over between calls.

Uploaded by

liman69609
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 6

Example: Find the factorial of a number

# take input from the user


num = as.integer(readline(prompt="Enter a number: "))
factorial = 1
# check is the number is negative, positive or zero
if(num < 0)
{
print("Sorry, factorial does not exist for negative numbers")
}
else if(num == 0)
{
print("The factorial of 0 is 1")
}
else
{
for(i in 1:num)
{
factorial = factorial * i
}
print(paste("The factorial of", num ,"is",factorial))
}

R Functions
func_name <- function (argument)
{
statement
}
Example of a Function
pow <- function(x, y)
{
result <- x^y
print(paste(x,"raised to the power", y, "is", result))
}
How to call a function?
We can call the above function as follows.
>pow(8, 2)
[1] "8 raised to the power 2 is 64"
Named Arguments
pow(x = 8, y = 2)
[1] "8 raised to the power 2 is 64"
pow(y = 2, x = 8)
[1] "8 raised to the power 2 is 64"
pow(x=8, 2)
[1] "8 raised to the power 2 is 64"
pow(2, x=8)
[1] "8 raised to the power 2 is 64"
Default Values for Arguments
pow <- function(x, y = 2)
{
result <- x^y
print(paste(x,"raised to the power", y, "is", result))
}
pow(3)
[1] "3 raised to the power 2 is 9"
pow(3,1)
[1] "3 raised to the power 1 is 3"
R Return Value from Function
return(expression)

Example: return()
check <- function(x)
{
if (x > 0)
{
result <- "Positive"
}
else if (x < 0) { result <- "Negative"
}
else
{
result <- "Zero"
}
return(result)
}
> check(1)
[1] "Positive"
> check(-10)
[1] "Negative"
> check(0)
[1] "Zero"

Functions without return()


check <- function(x)
{ if (x > 0)
{
result <- "Positive"
}
else if (x < 0) { result <- "Negative"
}
else
{
result <- "Zero"
}
result
}

Multiple Returns
multi_return <- function()
{
my_list <- list("color" = "red", "size" = 20, "shape" = "round") return(my_list)
}

a <- multi_return()
a$color
[1] "red"

a$size
[1] 20

a$shape
[1] "round"
Lazy Evaluation of Function
Arguments to functions are evaluated lazily, which means so they are evaluated only
when needed by the function body.
# Create a function with arguments.
new.function <- function(a, b)
{
print(a^2)
print(a)
print(b)
}
# Evaluate the function without supplying one of the arguments.
new.function(6)
When we execute the above code, it produces the following result:
[1] 36
[1] 6
Error in print(b) : argument "b" is missing, with no default

R Recursive Function
recursive.factorial <- function(x)
{
if (x == 0)
return (1)
else
return (x * recursive.factorial(x-1))
}

> recursive.factorial(0)
[1] 1

> recursive.factorial(5)
[1] 120

Scoping Rules
 The scoping rules of a language determine how a value is associated with a free
variable in a function.
 R uses lexical scoping or static scoping.
 Lexical scoping means that the values of free variables are searched for in the
environment in which the function was defined.
 An alternative to lexical scoping is dynamic scoping.
Why Lexical Scoping?
 Lexical Scoping is a set of rules that helps to determine how R represents the value
of a symbol.
 It is an in-built rule in R which automatically works at the language level.
Consider the following example:
f <- function(x, y)
{
x*y*z
}
In this:
 x and y are formal arguments
 z as the free variable
Therefore, the scoping rules of the language determine how values are assigned to
free variables. Free variables are not formal arguments and not local variables that are
assigned inside of the function body.

Principles of Lexical Scoping


There are four basic principles behind R’s implementation of lexical scoping:
1. Name Masking
2. Functions vs variables
3. A fresh start
4. Dynamic Lookup

Name Masking
The following example illustrates the most basic principle of lexical scoping, and you
should have no problem predicting the output.
 If variable is not defined inside the function:
Example:
c <- 10
f <- function(a, b)
{
a+b+c
}
f(8, 5)
 Output:
 [1] 23
 It takes the c value as 10 and then adds these numbers and finally we are
having 23 as output.
 If name is not defined inside the function:
If a name isn’t defined inside a function, R will look one level up.
Example:
a <- 10
b <- function()
{
c <- 11
c(a, c)
}
b()
 Output:
 [1] 10 11

 When one function is defined inside another function:


The same rules apply if a function is defined inside another function: look inside the
current function, then where that function was defined, and so on, all the way up to
the global environment, and then on to other loaded packages.
Example:
a <- 10
g <- function()
{
b <- 20
h <- function()
{
c <- 30
c(a, b, c)
}
h()
}
g()
 Output:
 [1] 10 20 30

 When functions are created by another function:


The same rules apply to closures, functions created by other functions.
Example:
a <- function(z){
b <- 10
function(){
z+4*b
}
}
x <- a(10)
x()
 Output:
 [1] 50
 R returns the accurate value of b after calling the function because x preserves the
environment in which it was defined. The environment includes the value of b.

Functions vs Variables
The same principles apply regardless of the type of associated value — finding
functions works exactly the same way as finding variables:
Example:
a <- function(x) 10 * x
b <- function(){
a <- function(x) x + 10
a(12)
}
b()

Output:
[1] 22
A Fresh Start
When a function is called, a new environment is created every time. Each
acknowledgement is completely independent because a function cannot tell what
happened when it was run last time.
Example:
a <- function(){
if(!exists("z"))
{
z <- 10
}
else
{
z <- z+10
}
z
}
a()

Output:
[1] 10
Dynamic Lookup
Lexical scoping controls where to look for values not when to look for them. R looks for
the values when the function is executed not when it is created. The output of the
function can be different depending on objects outside its environment.

Example:
g <- function() x^3
x <- 10
g()

Output:
[1] 1000
There is a function in R which is findGlobals() from codetools and it helps us to find all
global variables being used in a function and lists all the external dependencies of a
function. findGlobals() find the global variables and functions which are used by the
closure.

Example:
aGlobal <- rnorm(10)
bGlobal <- rnorm(10)

f <- function()
{
a <- aGlobal
b <- bGlobal
plot(b ~ a)
}
codetools::findGlobals(f)

Output:
[1] "{" "~" "<-" "aGlobal" "bGlobal" "plot"
We can manually change the environment to the empty
environment emptyenv(). emptyenv() is a totally empty environment.

You might also like