Below are the solutions to these exercises on functions. If you obtained a different (smarter, vectorized, etc) solution, please post as a comment below.

# Exercise 1 f.sum <- function (x, y) { r <- x + y r } f.sum(5, 10)

## [1] 15

# Exercise 2 f.exists <- function (v, x) { exist <- FALSE i <- 1 while (i <= length (v) & !exist) { if (v[i] == x) { exist <- TRUE } i <- 1 + i } exist } f.exists(c(1:10), 10)

## [1] TRUE

f.exists(c(9, 3, 1), 10)

## [1] FALSE

# Exercise 3 f.class <- function (df) { for (i in 1:ncol(df)) { cat(names(df)[i], "is", class(df[, i]), "\n") } } f.class(cars)

## speed is numeric ## dist is numeric

# Exercise 4 f.uniq <- function (v) { s <- c() for(i in 1:length(v)) { if(sum(v[i] == s) == 0) { s <- c(s, v[i]) } } s } f.uniq(c(9, 9, 1, 1, 1, 0))

## [1] 9 1 0

# Exercise 5 f.count <- function (v, x) { count <- 0 for (i in 1:length(v)) { if (v[i] == x) { count <- count + 1 } } count } f.count(c(1:9, rep(10, 100)), 10)

## [1] 100

# Exercise 6 desi <- function(x, med=FALSE) { mean <- round(mean(x), 1) stdv <- round(sd(x), 1) cat("Mean is:", mean, ", SD is:", stdv, "\n") if(med) { median <- median(x) cat("Median is:", median , "\n") } } desi(1:10, med=TRUE)

## Mean is: 5.5 , SD is: 3 ## Median is: 5.5

# Exercise 7 f.div <- function(n) { i <- 2 counter <- 0 while(i <= n/2) { if(n%%i==0) { counter <- counter + 1 cat (i ,"\n") } i <- i + 1 } counter } f.div(13)

## [1] 0

f.div(16)

## 2 ## 4 ## 8

## [1] 3

# Exercise 8 f.na <- function (df, otherna) { for(i in 1:ncol (df)) { for(j in 1:nrow (df)) { if(df[j,i] == otherna) { df[j,i] <- NA } } } df } carsnew <- f.na(cars, 10)

Johannes says

In my opinion, solution 2 is much easier and faster if you use “%in%” :

# Exercise 2

f.exists <- function (v, x) {

return(x %in% v)

}

f.exists(c(1:10),10)

## [1] TRUE

r-exercises says

Hi Johannes,

Thanks for sharing your easier and faster solutions! Indeed, the solutions shown were not optimized for speed or brevity. I will add an explanation and some further instructions on the exercises page. Thanks again for your feedback!

Johannes says

Exercise 4 can be solved much smarter with only one command line in the function or (even better) without an own function but rather with the base function “unique”:

v <- c(9, 9, 1, 1, 1, 0)

unique(v)

## [1] 9 1 0

Johannes says

Another faster solution for exercise 5:

v <- c(1:9, rep(10, 100))

x <- 10

length(which(v == x))

## [1] 100

The "which()" function gives the indices of vector v which are identical with x and length calculates the numbers of this indices.

yvesCR says

even simpler:

v <- c(1:9, rep(10, 100))

x <- 10

sum(v == x)

## [1] 100

sum the TRUE cases, which are equal to 1.

Johannes says

In exercise 8 it´s not necessary to build a for loop over all rowes, because you can handle every column as vector and than you can use the function “which()”.

Here is my solution to this problem:

f.na <- function (df, otherna) {

for(i in 1:ncol (df)) {

index <- which(df[,i] == otherna)

df[,i][index] <- NA

}

df

}

carsnew <- f.na(cars, 10)

Jiri Makovicka says

# Exercise 2

f0, TRUE,FALSE)

}

# Exercise 4

remDup <- function(x){

(x<-x[!duplicated(x)])

}

# Exercise 5

howMany<-function(x,i){

length(which(x==i))

}

# Exercise 8

fNA<-function(df,i){

for(j in names(df)) {

x<-df[,j]

x[which(x==i)]<-NA

df[,j]<-x

}

df

}

Jiri Makovicka says

# Exercise 2

f0, TRUE,FALSE)

}

Vaidotas Zemlys says

Are the answers intentionally bad? I have nothing against loops, but in this case their use is unnecessarily excessive.

r-exercises says

Hi Vaidotas,

No, not intentionally. I agree that use of loops can be avoided by vectorization. Thanks for pointing this out!

oleh says

ex7fun1)

for (i in 2L:rsx)

{ m=x/i

if (m==round(m))

{

retvect=c(retvect,i)

retvect2=c(m,retvect2)

}

}

if (!fullsquare)

retvect=c(retvect,retvect2)

else

retvect=c(retvect,retvect2[-1])

if (prn)

print(retvect)

length(retvect)

}

# compare

system.time(f.div(2^20))

system.time(ex7fun(2^20))

Jiri Makovicka says

# Exercise 2

# My first function for solution of exercise 2 above was interpreted by Web server wrongly.

# Here is the right version.

f0, TRUE,FALSE)

}

r-exercises says

Hi Jiri,

That’s strange. Would you mind sending me your solution by email, so I can check why it’s not processed properly by the web server? Please email to [email protected].

Jiri Makovicka says

# Once more bad interpretation.

# I will try it now for the last time:

# Exercise 2

f0, TRUE,FALSE)

}

Jaynal Abedin says

# Exercise 1: Assumed x is a vector and not necessarily only 2 element

fun1 <- function(x)

{

return(as.vector(x%*% rep(1,length(x))))

}

fun1(x=c(1,2,3,4))

# Exercise 2

fun2 <- function(vec,x)

{

return(any(vec==x))

}

fun2(vec=c(1,2,3),x=3)

# Exercise 3 : Example data is the default iris data

fun3 <- function(dat)

{

return(apply(dat,2,class))

}

fun3(iris)

Michael says

These solutions are intended to be useful exercises for beginners. They serve their purpose well. Thanks!

ahmed says

a <- function(x,y){x+y}

ahmed says

ex-2)

True <- function(vect,x){ifelse(x %in% vect,T,F)}

Brian H says

What a great thread with even greater answers. I’m a beginner to programming in R and all of the examples listed by everyone helped me learn a little more each time I read them.

Thanks!

Sergio says

Not as beautifully verbose but quicker solution to Exercise 3:

sapply(df, class)

Sergio says

Solution to 4:

(without using built-in unique())

uniq <- function(vec){

as.vector(which(table(vec)==1))

}

Sergio says

Also, using unique() on a matrix will not give you unique numbers, but using which(table(matrix)==1) will.

Deepanshu Sinha says

Solution to Ex2.

The test expression in while loop does not make sense logically because in RHS of while loop it gives a logical value that is TRUE/FALSE. Then how is value of i comparable with logical value.

Thank you