0% found this document useful (0 votes)
3 views28 pages

Unit2 R Notes

The document outlines control statements in R programming, detailing eight types including if, if-else, for loops, while loops, and others. It provides syntax and examples for each control structure, illustrating their functionality and use cases. Additionally, it discusses looping functions like apply(), lapply(), and others, along with logical and relational operators in R.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views28 pages

Unit2 R Notes

The document outlines control statements in R programming, detailing eight types including if, if-else, for loops, while loops, and others. It provides syntax and examples for each control structure, illustrating their functionality and use cases. Additionally, it discusses looping functions like apply(), lapply(), and others, along with logical and relational operators in R.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Statistical and R programming

UNIT 2
Control statements in R

Control statements are expressions used to control the execution and flow of the
program based on the conditions provided in the statements. These structures are
used to make a decision after assessing the variable.
In R programming, there are 8 types of control statements as follows:
if condition
if-else condition
for loop
nested loops
while loop
repeat and break statement
return statement
next statement

if condition
This control structure checks the expression provided in parenthesis is true or not. If
true, the execution of the statements in braces {} continues.
Syntax:
if(expression){
statements
....
....
}

Ex:
x <- 100

if(x > 10){


print(x, "is greater than 10")
}

Output
"100 is greater than 10"

if-else condition
It is similar to if condition but when the test expression in if condition fails, then
statements in else condition are executed.
Syntax:
if(expression){
statements
....
....
}
else{
statements
....
....
}
Ex:
x <- 5

# Check value is less than or greater than 10


if(x > 10){
print(paste(x, "is greater than 10"))
}else{
print(paste(x, "is less than 10"))
}
Output:
"5 is less than 10"

for loop
It is a type of loop or sequence of statements executed repeatedly until exit
condition is reached.
Syntax:
for(value in vector){
statements
....
....
}
Ex:
x <- letters[4:10]

for(i in x){
print(i)
}
Output:
[1] "d"
[1] "e"
[1] "f"
[1] "g"
[1] "h"
[1] "i"
[1] "j"

Nested loops
Nested loops are similar to simple loops. Nested means loops inside loop. Moreover,
nested loops are used to manipulate the matrix.
Ex:
# Defining matrix
m <- matrix(2:15, 2)

for (r in seq(nrow(m))) {
for (c in seq(ncol(m))) {
print(m[r, c])
}
}
Output:
[1] 2
[1] 4
[1] 6
[1] 8
[1] 10
[1] 12
[1] 14
[1] 3
[1] 5
[1] 7
[1] 9
[1] 11
[1] 13
[1] 15

while loop
while loop is another kind of loop iterated until a condition is satisfied. The testing
expression is checked first before executing the body of loop.
Syntax:
while(expression){
statement
....
....
}
Ex:
x=1

# Print 1 to 5
while(x <= 5){
print(x)
x=x+1
}
Output:
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5

repeat loop and break statement


repeat is a loop which can be iterated many number of times but there is no exit
condition to come out from the loop. So, break statement is used to exit from the
loop. break statement can be used in any type of loop to exit from the loop.
Syntax:
repeat {
statements
....
....
if(expression) {
break
}
}
Ex:
x=1

# Print 1 to 5
repeat{
print(x)
x=x+1
if(x > 5){
break
}
}
Output:
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
return statement
return statement is used to return the result of an executed function and returns
control to the calling function.
Syntax:
return(expression)
Ex:
# Checks value is either positive, negative or zero
func <- function(x){
if(x > 0){
return("Positive")
}else if(x < 0){
return("Negative")
}else{
return("Zero")
}
}

func(1)
func(0)
func(-1)

Output:
[1] "Positive"
[1] "Zero"
[1] "Negative"

next statement
next statement is used to skip the current iteration without executing the further
statements and continues the next iteration cycle without terminating the loop.
Ex:
# Defining vector
x <- 1:10

# Print even numbers


for(i in x){
if(i%%2 != 0){
next #Jumps to next loop
}
print(i)
}
Output:
[1] 2
[1] 4
[1] 6
[1] 8
[1] 10

Looping over non-vector sets in R


One of the biggest issues with the “for” loop is its memory consumption and its
slowness in executing a repetitive task. And when it comes to dealing with large data
set and iterating over it, for loop is not advised. R provides many alternatives to be
applied to vectors for looping operations that are pretty useful when working
interactively on a command line. we deal with apply() function and its variants:
apply()
lapply()
sapply()
tapply()
mapply()
Looping Function Operation

Applies a function over the margins of an array or


apply()
matrix

lapply() Apply a function over a list or a vector

sapply() Same as lapply() but with simplified results

tapply() Apply a function over a ragged array

mapply() Multivariate version of lapply()

apply(): This function applies a given function over the margins of a given array.
apply(array, margins, function, …)
array = list of elements
margins = dimension of the array along which the function needs to be applied
function = the operation which you want to perform

Example:
# R program to illustrate
# apply() function

# Creating a matrix
A = matrix(1:9, 3, 3)
print(A)

# Applying apply() over row of matrix


# Here margin 1 is for row
r = apply(A, 1, sum)
print(r)

# Applying apply() over column of matrix


# Here margin 2 is for column
c = apply(A, 2, sum)
print(c)

Output:
[, 1] [, 2] [, 3]
[1, ] 1 4 7
[2, ] 2 5 8
[3, ] 3 6 9
[1] 12 15 18
[1] 6 15 24

lapply(): This function is used to apply a function over a list. It always returns a list of
the same length as the input list.
lapply(list, function, …)
list = Created list
function = the operation which you want to perform
Example:
# R program to illustrate
# lapply() function

# Creating a matrix
A = matrix(1:9, 3, 3)

# Creating another matrix


B = matrix(10:18, 3, 3)

# Creating a list
myList = list(A, B)

# applying lapply()
determinant = lapply(myList, det)
print(determinant)
Output:
[[1]]
[1] 0

[[2]]
[1] 5.329071e-15

sapply(): This function is used to simplify the result of lapply(), if possible.


Unlike lapply(), the result is not always a list. The output varies in the following
ways:-
If output is a list containing elements having length 1, then a vector is returned.
If output is a list where all the elements are vectors of same length(>1), then a
matrix is returned.
If output contains elements which cannot be simplified or elements of different
types, a list is returned.
sapply(list, function, …)
list = Created list
function = the operation which you want to perform
Example:
# R program to illustrate
# sapply() function

# Creating a list
A = list(a = 1:5, b = 6:10)

# applying sapply()
means = sapply(A, mean)
print(means)
Output:
ab
38
A vector is returned since the output had a list with elements of length 1.

tapply(): This function is used to apply a function over subset of vectors given by a
combination of factors.
tapply(vector, factor, function, …)
vector = Created vector
factor = Created factor
function = the operation which you want to perform
Example:
# R program to illustrate
# tapply() function

# Creating a factor
Id = c(1, 1, 1, 1, 2, 2, 2, 3, 3)

# Creating a vector
val = c(1, 2, 3, 4, 5, 6, 7, 8, 9)

# applying tapply()
result = tapply(val, Id, sum)
print(result)
Output:
1 2 3
10 18 17
How does the above code work?
mapply(): It’s a multivariate version of lapply(). This function can be applied over
several list simultaneously.
mapply(function, list1, list2, …)
function = the operation which you want to perform
list1, list2 = Created lists
Example:
# R program to illustrate
# mapply() function

# Creating a list
A = list(c(1, 2, 3, 4))

# Creating another list


B = list(c(2, 5, 1, 6))

# Applying mapply()
result = mapply(sum, A, B)
print(result)
Output:
24

If-Else statement in R

R supports the usual logical conditions from mathematics:


Operator Name Example

== Equal x == y

!= Not equal x != y

> Greater than x>y


< Less than x<y

>= Greater than or equal to x >= y

<= Less than or equal to x <= y


These conditions can be used in several ways, most commonly in "if statements" and
loops.

The if Statement
An "if statement" is written with the if keyword, and it is used to specify a block of
code to be executed if a condition is TRUE:
Example:
a<-33
b<-200
if(b>a){
print(“b is greater than a”)
}

In this example we use two variables, a and b, which are used as a part of the if
statement to test whether b is greater than a. As a is 33, and b is 200, we know that
200 is greater than 33, and so we print to screen that "b is greater than a".
R uses curly brackets { } to define the scope in the code.

Else If
The else if keyword is R's way of saying "if the previous conditions were not true,
then try this condition":
Example
a <- 33
b <- 33

if (b > a) {
print("b is greater than a")
} else if (a == b) {
print ("a and b are equal")
}
In this example a is equal to b, so the first condition is not true, but the else
if condition is true, so we print to screen that "a and b are equal".
You can use as many else if statements as you want in R.

If Else
The else keyword catches anything which isn't caught by the preceding conditions:
Example
a<-200
b<-33
if(b>a){
print(“b is greater than a”)
}else if(a==b){
print(“a and b are equal”)
}else{
print(“a is greater than b”)
}
In this example, a is greater than b, so the first condition is not true, also the else
if condition is not true, so we go to the else condition and print to screen that "a is
greater than b".
You can also use else without else if:
Example
a<-200
b<-33
if(b>a){
print(“b is greater than a”)
} else{
print(“a is greater than a”)
}

OPERATORS
R has many operators to carry out different mathematical and logical
operators.
Types of operators are:
Arithmetic Operators
Relational Operators
Logical Operators
Assignment Operators
Miscellaneous Operators

Arithmetic Operators:
These operators are used to carry out mathematical operations like addition
and multiplication. The list of arithmetic operators available in R are:
Operator Description Example
+ Adds two vectors >v<-c(2,5.5,6)
>t<-c(8,3,4)
>print(v+t)
[1] 10.0 8.5 10.0
- Subtracts second vector from the first >v<-c(2,5.5,6)
>t<-c(8,3,4)
>print(v-t)
[1] -6.0 2.5 2.0
* Multiplies both vectors >v<-c(2,5.5,6)
>t<-c(8,3,4)
>print(v*t)
[1] 16.0 16.5 24.0
/ Divide the first vector with the >v<-c(2,5.5,6)
second >t<-c(8,3,4)
>print(v/t)
[1]0.250000 1.833333
1.500000

%% Give the remainder of the first vector >v<-c(2,5.5,6)


with the second >t<-c(8,3,4)
>print(v%%t)
O/p 2.0 2.5 2.0
%/% The result of division of first vector >v<-c(2,5.5,6)
with second (quotient) >t<-c(8,3,4)
>print(v%/%t)
O/p 0 1 1
^ The first vector raised to the >v<-c(2,5.5,6)
exponent of second vector >t<-c(8,3,4)
>print(v^t)
O/p 256.000 166.375
1296.000

Relational Operator:
Relational Operators are used to compare between values. Each element of the first
vector is compared with the corresponding element of the second vector. The result
of comparison is a boolean value.
Operator Description Example
> Checks if each element of >v<-c(2,5.5,6,9)
the first vector is greater >t<-c(8,2.5,1,9)
than the corresponding >print(v>t)
element of the second O/p FALSE TRUE TRUE
vector FALSE
< Checks if each element of >v<-c(2,5.5,6,9)
the first vector is less than >t<-c(8,2.5,1,9)
the corresponding >print(v<t)
element of the second O/p TRUE FALSE FALSE
vector FALSE
== Checks if each element of >v<-c(2,5.5,6,9)
the first vector is equal to >t<-c(8,2.5,1,9)
the corresponding >print(v==t)
element of the second O/p FALSE FALSE FALSE
vector TRUE
<= Checks if each element of >v<-c(2,5.5,6,9)
the first vector is less than >t<-c(8,2.5,1,9)
or equal to the >print(v<=t)
corresponding element of O/p TRUE FALSE FALSE
the second vector TRUE
>= Checks if each element of >v<-c(2,5.5,6,9)
the first vector is greater >t<-c(8,2.5,1,9)
than or equal to the >print(v>=t)
corresponding element of O/p FALSE TRUE TRUE
the second vector TRUE
!= Checks if each element of >v<-c(2,5.5,6,9)
the first vector is not >t<-c(8,2.5,1,9)
equal to the >print(v!=t)
corresponding element of O/p TRUE TRUE TRUE
the second element FALSE

Logical Operator:
It is applicable only to vectors of type logical, numeric or complex. Zero is
considered FALSE and non-zero numbers are taken as TRUE. Each element of the
first vector is compared with the corresponding element of the second vector. The
result of comparison is a boolean value.
Operator Description Example
& It is called element-wise >v<-c(3,2,TRUE,2+3i)
logical AND operator. It >t<-c(4,1,FALSE,2+3i)
combines each element of >print(v&t)
the first vector with the O/p TRUE TRUE FALSE
corresponding element of TRUE
the second vector and
gives a output TRUE if
both the elements are
TRUE
| It is called element-wise >v<-c(3,0,TRUE,2+3i)
logical OR operator. It >t<-c(4,0,FALSE,2+3i)
combines each element of >print(v|t)
the first vector with the O/p TRUE FALSE TRUE
corresponding element of TRUE
the second vector and
gives a output TRUE if one
the elements is TRUE
! It is called logical NOT >v<-c(3,2,FALSE,2+3i)
operator. Takes each >print(!v)
element of the vector and O/p FALSE FALSE TRUE
gives the opposite logical FALSE
value

The logical operator && and || considers only the first element of the vectors and
give a vector of single element as output

Operator Description Example


&& Called logical AND >v<-c(3,0,TRUE,2+2i)
operator. Takes first >t<-c(1,3,FALSE,2+3i)
element of both the >print(v&&t)
vectors and gives the O/p TRUE FALSE FALSE
TRUE only if both are TRUE
TRUE
|| Called logical OR operator. >v<-c(3,0,TRUE,2+2i)
Takes first element of >t<-c(1,3,FALSE,2+3i)
both the vectors and gives >print(v&&t)
the TRUE if one of them is O/p TRUE TRUE TRUE
TRUE TRUE

Assignment Operators:
These operators are used to assign values to vectors
Operators Description Example
<- Called left assignment >v1<-c(3,1,TRUE,2+2i)
Or >v2=c(3,1,TRUE,2+2i)
= >v3<<-c(3,1,TRUE,2+2i)
<<- >print(v1)
>print(v2)
>print(v3)
O/p 3+0i 1+0i 1+0i 2+2i
3+0i 1+0i 1+0i 2+2i
3+0i 1+0i 1+0i 2+2i
-> Called right assignment >c(3,1,TRUE,2+2i)->v1
Or >c(3,1,TRUE,2+2i)->> v2
->> >print(v1)
>print(v2)
O/p 3+0i 1+0i 1+0i 2+2i
3+0i 1+0i 1+0i 2+2i

Miscellaneous Operators:
These operators are used for specific purpose and not general mathematical
or logical computation.

Operator Description Example


: Colon operator. >v<-2:8
It creates the >print(v)
series of O/p 2 3 4 5 6 7 8
numbers in
sequence for a
vector
%in% This operator is >v1<-8
used to identify >v2<-12
if an element >t<-1:10
belongs to a >print(v1%in%t)
vector >print(v2%in%t)
O/p TRUE
FALSE
%*% This operator is >m=matrix(c(2,6,5,3),nrow=2,ncol=2,byrow=TRUE)
used to >t=m%*%m
multiply a >print(t)
matrix with its
transpose

Default Arguments

Arguments are the parameters provided to a function to perform operations


in a programming language. In R programming we can use as many arguments as we
want and are separated by a comma. There is no limit on the number of arguments
in a function in R.
Adding arguments in R:
We can pass an argument to a function while calling the function by simply
giving the value as an argument inside the parenthesis.
Syntax:
function_name<-function(arg1,arg2,…)
{
Code
}

Ex 1:
calculate_square<-function(n)
{
result<-n^2
return(result)
}

value1<-2
calculate_square(value1)

value2<-3.2
calculate_square(value2)

O/p
[1]4
[1]10.24

Ex 2:
calculate_square<-function(n)
{
result<-n^2
return(result)
}
calculate_square(2)
calculate_square(3.2)

O/p
[1]4
[1]10.24

Adding multiple arguments in R


A function in R programming can have multiple arguments too
Ex:
divisible<-function(a,b)
{
if(a%%b==0)
{
return(paste(a," is divisible by ",b))
}else{
return(paste(a," is not divisible by",b))
}
}

divisible(100,5)
divisible(7,3)
divisible(9,2)

O/p
"100 is divisible by 5"
"7 is not divisible by 3"
[1] "9 is not divisible by 2"

Adding Default value in R:


The default value in a function is a value that is not required to specify each
time the function is called. If the value is passed by the user, then the user-defined
value is used by the function otherwise the default value is used.
Ex:
divisible<-function(a,b=3){
if(a%%b==0){
return(paste(a,"is divisible by", b))
}
else{
return(paste(a,"is not divisible by",b))
}
}
divisible(12)
divisible(10,5)

O/p:
"12 is divisible by 3"
"10 is divisible by 5"

Dot argument:
Dot argument(…) is also known as ellipsis which allows the function to take
an undefined number of arguments. It allows the function to take an arbitrary
number of arguments.
Ex:
func<-function(n,...)
{
l<-list(n,...)
paste(l,collapse=",")
}
func(5,1L,6i,TRUE,"DOT Operator")

O/p
[1] "5,1,0+6i,TRUE,DOT Operator"

Function as argument:
In R programming, functions can be passed to another functions as
arguments.
Ex:
func<-function(n,fun1)
{
return(fun1(x))
}
func(c(1:10),sum)
func(c(1,2,3,4),mean)

O/p
[1] 36
[1] 4.5

RETURN VALUES

Functions are generally used for computing so value, so they need a


mechanism to supply that value back the caller. This is called returning.
The return value a function can be any R object. Although the return value is often a
list, it could even be another function
You can transmit a value back to the called explicitly calling return(). Without this call,
the value of the last executed statement will be returned by default.
If the last statement in the call function is a for() statement, which returns the value
NULL

#First build it without explicit return


num<-function(x)
{
x*2
}
num(5)
O/p
[1]10

#now build it with an explicit return


num<-function(x)
{
Return(x*2)
}
num(5)

O/p
[1]10

#build it again, this time with another argument after the explicit return
> num<-function(x)
+{
+ return(x*2)
+ print("RAM")
+ return(17)
+}
> num(5)

O/p
[1] 10

#if the last statement is for loop or any empty statement then it return NULL
> num<-function(x)
+{
+
+}
> num(5)

O/p
NULL

R function to return multiple values as list


> arithmetic<-function(value1,value2){
+ add=value1+value2
+ sub=value1-value2
+ prod=value1*value2
+ div=value1/value2
+ return(list(add,sub,prod,div))
+}
> arithmetic(10,20)

O/p
[[1]]
[1] 30

[[2]]
[1] -10

[[3]]
[1] 200

[[4]]
[1] 0.5

Deciding whether to explicitly call return():


The R idiom is to avoid explicit calls to return(). One of the reasons cited for
this approach is that calling that function lengthens execution time. However, unless
the function is very short, the time saved is negligible, so this might not be the most
compelling reason to refrain from using return(). But it usually isn’t needed.

#Example to count the odd numbers with no return statements


> oddcount<-function(x){
+ k<-0
+ for(n in x){
+ if(n%%2!=0)
+ k=k+1
+ }
+ k
+}
> oddcount(c(12,2,5,9,7))
[1] 3

#Example to count the odd numbers with return statement


oddcount<-function(x){
k<-0
for(n in x){
if(n%%2!=0)
k=k+1
}
return(k)
}
oddcount(c(12,2,5,9,7))
3

Good software design can glance through a function’s code and immediately spot
the various points at which contains is returned to the called. The easiest way to
accomplish this to use an explicit return() call in all lines in the middle of the code
that cause a return.
RETURNING COMPLEX OBJECTS
In R, when we refer to “complex objects”,we generally mean data structures that can
hold multiple types of data or structures such as lists, data-frames and matrices.
These complex objects can be created and returned from functions to encapsulate
and organize related information.
Ex:
 Returning a list
> create_complex_list<-function(x,y){
+ returnlist<-list(add=x+y,sub=x-y,prod=x*y,div=x/y)
+ return(returnlist)
+}
> create_complex_list(5,3)
$add
[1] 8

$sub
[1] 2

$prod
[1] 15

$div
[1] 1.666667

 Returning dataframe
> create_complex_dataframe<-function(x,y){
+ returndf<-[Link](add=x+y,sub=x-y,prod=x*y,div=x/y)
+ return(returndf)
+}
> create_complex_dataframe(5,3)
add sub prod div
1 8 2 15 1.666667

 Returning matrices
> create_complex_matrix<-function(x,y){
+ returnmatrix<-matrix(c(x+y,x-y,x*y,x/y),nrow=2)
+ return(returnmatrix)
+}
> create_complex_matrix(5,3)
[,1] [,2]
[1,] 8 15.000000
[2,] 2 1.666667

FUNCTIONS ARE OBJECTIVES


R functions are first class objects (of the class “function”), meaning that they
can be used for the most part just like other objects. This is seen in the syntax of
function creation.
g<-function(x){
return(x+1)
}

Function() is a built-in R function whose job is to create functions, on the right hand
side, there are really two arguments to function(): The first is the formal argument
list for the function i.e., x & the second is the body of the function return (x+1).

 formals(): get or set the formal arguments of a function


> formals(g)
$x

 body(): get or set the body of a function


> body(g)
{
return(x + 1)
}
 Replacing body of the function: quote() is used to substitute expression
> body(g)<-quote(2*x+3)
> body(g)
2*x+3
 Typing the name of an object results in printing that object to the screen which
is similar to all objects
> g
function (x)
2 * x + 3
 Since functions are objects, you can also assign them, use them as arguments to
other functions and so on.
> f1<-function(a,b){
+ return(a+b)
+ }
> f2<-function(a,b){
+ return(a-b)
+ }
> f<-f1
> f(5,3)
[1] 8

 > g<-function(h,a,b){
+ h(a,b)
+ g(f1,2,3)
+ }

NO POINTERS IN R
R does not have variables corresponding to pointers or references like c language.
This can make programming more difficult in some cases.
The fundamental thought is to create a class constructor and have every
instatiation of class be its own environment. One can then pass the object/ condition
into a function and it will be passed by reference instead of by value, because unlike
other R objects, environments are not copied when passed to functions. Changes to
the objects in the function will change the object in he calling frame. In this way, one
can operate on the object and change internal elements without having to create a
copy of the object when the function is called, nor pass the entire object back from
the function. For large objects, this saves memory and time.
Ex:
> x<-c(12,4,6)
> sort(x)
[1] 4 6 12
> x
[1] 12 4 6

The argument to sort() does not change. If we do want x to change in this R code, the
solution is to reassign the arguments:
> x<-sort(x)
> x
[1] 4 6 12

If a function has several output then a solution is to gather them together into a list,
call the function with this list as an argument, have the function return the list, and
then reassign to the original list.
Ex:
> y<-function(x){
+ odds<-which(x%%2!=0)
+ evens<-which(x%%2==0)
+ list(o=odds,e=evens)
+ }
> x<-c(2,34,1,5)
> y(x)
$o
[1] 3 4

$e
[1] 1 2

RECURSION
Recursion is a programming technique in which, a function calls itself repeatedly for
some input. To solve a problem of type x by writing a recursive function f():
1. Break the original problem of type x into one or more smaller problems of type x
2. Within f(), call f() on each of the smaller problems
3. Within f(), piece together the results of (b) to solve the original problem

Ex: Factorial of a number


> factorial<-function(n){
+ if(n==0){
+ return(1)
+ }
+ else{
+ return(n*factorial(n-1))
+ }
+ }
> factorial(5)
[1] 120

Tracing
QUICK SORT IMLEMENTATION
A quick sort is also known as partition-exchange sort and is based on Divide and
Conquer Algorithm design method. This was proposed by C.A.R Hoare. The basic idea
of quick sort is very simple. We consider one element at a time (pivot element). We
have to move the pivot element to the final position that it should occupy in the final
sorted list. While identifying this position, we arrange the elements, such that the
elements to the left of the pivot element will be less than the pivot element and
elements to the right of the pivot element will be greater than the pivot element.
There by dividing the list 2 parts. We have to apply quick sort on these 2 parts
recursively until the entire list is sorted
Ex:
> quicksort<-function(arr){
+ if(length(arr)<=1){
+ return(arr)
+ }
+ pivot<-arr[1]
+ less_than_pivot<-arr[arr<pivot]
+ equal_to_pivot<-arr[arr==pivot]
+ greater_than_pivot<-arr[arr>pivot]
+ sorted_less<-quicksort(less_than_pivot)
+ sorted_greater<-quicksort(greater_than_pivot)
+ sorted_array<-c(sorted_less,equal_to_pivot,sorted_greater)
+ return(sorted_array)
+ }
> unsorted_array<-c(4,5,3,2,6)
> sorted_array<-quicksort(unsorted_array)
> cat("Unsorted array",unsorted_array)
Unsorted array 4 5 3 2 6
> cat("sorted_array",sorted_array)
sorted_array 2 3 4 5 6

arr Pivot Less than Equal to Greater Sorted Sorted Sorted


pivot pivot than pivot Less Greater array
Pivot Arr[arr<pivot Arr[arr==p Arr[arr>piv Quicksort(les Quicksort(gre
= ] ivot] ot] sthanpivot) aterthanpivot
Arr[1 )
]
4,5,3,2,6 4 3,2 4 5,6 Quicksort(3,
2)
3,2 3 2 3 Quicksort(2)
2 2,3 Quicksort(5,
6)
5,6 5 5 6 Quicksort(6)
6 5,6 2,3,4,5,6

BINARY SEARCH TREE


The nature of binary search trees implies that at any node, all of the elements in the
node’s left subtree are less than or equal to the value sorted in this node, while the
subtree stores the elements that are larger than the value in this node.

Ex: 8,5,2,6,20
8
/\
5 20
/\
2 6

Sorting the values: 2,5,6,8,20

Program

Node<-function(key){
list(key=key,left=NULL,right=NULL)
}

#function to insert key into the BST


insert<-function(root,key){
if([Link](root)){
return(Node(key))
}
if(key<root$key){
root$left=insert(root$left,key)
}
else if(key>root$key){
root$right=insert(root$right,key)
}
return(root)
}

#function to search for a key in the BST


search<-function(root,key){
if([Link](root)||root$key==key){
return(root)
}
if(key<root$key){
return(search(root$left,key))
}else{
return(search(root$right,key))
}
}

root<-NULL
keys_to_insert<-c(8,3,10,1,6,14,4,7,1,3)
for(key in keys_to_insert){
root<-insert(root,key)

}
#search for keys in the BST
keys_to_search<-c(6,5)
for(key in keys_to_search){
result<-search(root,key)
if(![Link](result)){
cat("key",key,"found in the BST.\n")
}else{
cat("key",key,"not found in the BST.\n")
}
}

O/p:
key 6 found in the BST.
key 5 not found in the BST.

ERROR HANDLING IN R
Error handling is a process in which we deal with unwanted or anomalous errors
which may cause abnormal termination of the program during its execution.
In R programming there are two ways to implement an error handling mechanism.
Either we can directly call the functions like stop() or warning() or we can use the
error options such as “warn” or “[Link]”.

Condition Handling in R:
There are basically three methods to handle such conditions and errors in R:
 try(): it helps us to continue with the execution of the program even when an
error occurs
 tryCatch(): It helps to handle the conditions and control whats happens based
on the conditions.
 withCallingHandlers(): It is alternative to tryCatch() that takes care of the local
handlers.

Try-catch-finally in R:
Unlike other programming languages such as Java, C++, and so on, the try-
catch-finally statements are used as a function in R. The main two condtions are
handled in tryCatch() are “errors” and “warnings”.
Syntax:
check=tryCatch({
expression
},warning=function(w){
code that handles the warnings
},error=function(e){
code that handles the errors
},finally=function(f){
clean up code
})

Ex:
# Function to simulate an error
divide_numbers <- function(x, y) {
if (y == 0) {
stop("Error: Division by zero")
}
return(x / y)
}

# Example using tryCatch


result <- tryCatch({
# Code that might throw an error
divide_numbers(10, 0)
}, error = function(e) {
# Code to handle the error
cat("Caught an error:", conditionMessage(e), "\n")
return(NA)
}, finally = {
# Code to be executed whether an error occurred or not
cat("Finally block executed\n")
})

# Result after error handling


print(result)

O/p
Caught an error: Error: Division by zero
Finally block executed
[1] NA

withCallingHandlers() in R:
In R, withCallingHandlers() is a variant of tryCatch(). The only difference is
tryCatch() deals with exiting handlers while withCallingHandlers() deal with local
handlers.

Ex:
# Function to simulate an error
divide_numbers <- function(x, y) {
if (y == 0) {
stop("Error: Division by zero")
}
return(x / y)
}

# Example using withCallingHandlers


result <- withCallingHandlers({
# Code that might throw an error
divide_numbers(10, 0)
}, error = function(e) {
# Code to handle the error
cat("Caught an error:", conditionMessage(e), "\n")
return(NA)
}, warning = function(w) {
# Code to handle a warning
cat("Caught a warning:", conditionMessage(w), "\n")
invokeRestart("muffleWarning") # Muffle the warning
})

# Result after handling conditions


print(result)

O/p
Caught an error: Error: Division by zero
Show Traceback

Rerun with Debug

Error in divide_numbers(10, 0) : Error: Division by zero


[1] NA

You might also like