> for(i in 1:3){
+ print(i)
+ }
[1] 1
[1] 2
[1] 3
> counter <- 0
> items <- 4:8
> for (i in items){
+ counter <- counter+1
+ cat("Now in loop",counter,"and item is",i,"\n")
+ }
Now in loop 1 and item is 4
Now in loop 2 and item is 5
Now in loop 3 and item is 6
Now in loop 4 and item is 7
Now in loop 5 and item is 8
> ind <- c(0.4, 3.2, 5.9, 1000)
> counter <- 0
> for (i in ind){
+ counter <- counter+1
+ cat("Index value in loop",counter,"is",i,"\n")
+ }
Index value in loop 1 is 0.4
Index value in loop 2 is 3.2
Index value in loop 3 is 5.9
Index value in loop 4 is 1000
The previous code can be written in the following way also-
> ind <- c(0.4, 3.2, 5.9, 1000)
> for (i in 1:length(ind)){
+ cat("Index value in loop",i,"is",ind[i],"\n")
+ }
Index value in loop 1 is 0.4
Index value in loop 2 is 3.2
Index value in loop 3 is 5.9
Index value in loop 4 is 1000
Expert solutions to R Studio statistics assignments.
(OPTIONAL PART) Example of a complicated code to find whether the objects in a list is matrix or not and if that is matrix then calculating the number of rows and columns and data types of that matrix.
Here is the list-
> mix <- list(obj1=c(3.4,1),
+ obj2=matrix(1:4,2,2),
+ obj3=matrix(c(T,T,F,T,F,F),3,2),
+ obj4="string here",
+ obj5=matrix(c("red","green","blue","yellow")))
> print(mix)
$obj1
[1] 3.4 1.0
$obj2
[,1] [,2]
[1,] 1 3
[2,] 2 4
$obj3
[,1] [,2]
[1,] TRUE TRUE
[2,] TRUE FALSE
[3,] FALSE FALSE
$obj4
[1] "string here"
$obj5
[,1]
[1,] "red"
[2,] "green"
[3,] "blue"
[4,] "yellow"
Creating space for the results with NA-
> name <- names(mix)
> is.mat <- rep(NA,length(mix))
> nr <- rep(NA,length(mix))
> nc <- rep(NA,length(mix))
> data.type <- rep(NA,length(mix))
Code for calculation-
> for (i in 1:length(mix)){
+ obj <- mix[[i]]
+ if(is.matrix(obj)){
+ is.mat[i] <- "YES"
+ nr[i] <- nrow(obj)
+ nc[i] <- ncol(obj)
+ data.type[i] <- class(as.vector(obj))
+ }else{
+ is.mat[i] <- "NO"
+ }
+ }
Showing the results using data frame-
> data.frame(name,is.mat,nr,nc,data.type,stringsAsFactors=FALSE)
name is.mat nr nc data.type
1 obj1 NO NA NA <NA>
2 obj2 YES 2 2 integer
3 obj3 YES 3 2 logical
4 obj4 NO NA NA <NA>
5 obj5 YES 4 1 character
> counter <- 1
> while (counter <=5){
+ cat("Loop",counter,"...\n")
+ counter <- counter+1
+ cat(ifelse(test = counter <=5,
+ yes = "Will continue the loop\n\n",
+ no = "Condition is false and will end loop\n---X---"))
+ }
Loop 1 ...
Will continue the loop
Loop 2 ...
Will continue the loop
Loop 3 ...
Will continue the loop
Loop 4 ...
Will continue the loop
Loop 5 ...
Condition is false and will end loop
---X---
The following code cycles through each row and stores the sum in row.sum-
> emat <- matrix(1:12,4,3)
> emat
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> row.sum <- rep(NA, nrow(emat))
> for (i in 1:nrow(emat)){
+ row.sum[i] <- sum(emat[i,])
+ }
> row.sum
[1] 15 18 21 24
The following code using apply is equivalent to the previous one and much simpler-
> apply(X=emat, MARGIN=1, FUN=sum)
[1] 15 18 21 24
> apply(emat,1,mean)
[1] 5 6 7 8
The MARGIN index follows the positional order of the dimension for matrices and arrays.
Here -
> emat
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> apply(emat,2,sum)
[1] 10 26 42
The following code finds the diagonals of the arrays-
> arr <- array(1:18,dim=c(3,3,2))
> arr
, , 1
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
, , 2
[,1] [,2] [,3]
[1,] 10 13 16
[2,] 11 14 17
[3,] 12 15 18
> apply(arr,3, diag)
[,1] [,2]
[1,] 1 10
[2,] 5 14
[3,] 9 18
> rmat <- matrix(round(runif(9,min=1,max=30)),3,3)
> rmat
[,1] [,2] [,3]
[1,] 27 17 4
[2,] 2 30 6
[3,] 1 23 27
> apply(rmat, 2, sort, decreasing=F)
[,1] [,2] [,3]
[1,] 1 17 4
[2,] 2 23 6
[3,] 27 30 27
tapply performs operations on subsets of the object of interest-
> df <- data.frame(age=c(22,20,NA,24,19),
+ sex=factor(c("M","F","F","M","M")),
+ stringsAsFactors=FALSE)
> df
age sex
1 22 M
2 20 F
3 NA F
4 24 M
5 19 M
> tapply(X=df$age, INDEX=df$sex, FUN=mean, na.rm=T)
F M
20.00000 21.66667
lapply can operate object by object on a list-
> arr <- list(obj1=c(3.4,1),
+ obj2=matrix(1:4,2,2),
+ obj3=matrix(c(T,T,F,T,F,F),3,2),
+ obj4="string here",
+ obj5=matrix(c("red","green","blue","yellow")))
> unlist(lapply(arr, FUN=is.matrix))
obj1 obj2 obj3 obj4 obj5
FALSE TRUE TRUE FALSE TRUE
sapply does the same work as previous but shows the output in a simpler way-
> sapply(arr,is.matrix)
obj1 obj2 obj3 obj4 obj5
FALSE TRUE TRUE FALSE TRUE
What sapply actually do is, it tries to simplify the output of lapply when possible. If the result is a list where every element is a vector of the same length then it returns a vector(when length=1)/matrix(length>1) ,and if not then it returns a list just like lapply.
> unlist(lapply(arr, FUN=is.matrix))
obj1 obj2 obj3 obj4 obj5
FALSE TRUE TRUE FALSE TRUE
In FUN argument, custom functions can also be defined -
> sapply(arr, function(x) ifelse(is.matrix(x), "Matrix", "Not Specified"))
obj1 obj2 obj3 obj4 obj5
"Not Specified" "Matrix" "Matrix" "Not Specified" "Matrix"
mapply() applies a Function to Multiple List or multiple Vector Arguments -
> set.seed(0)
> mapply(FUN = function(...) round(runif(...)),
+ n=c(1,5,3), min=c(1,2,9), max=10
+ )
[[1]]
[1] 9
[[2]]
[1] 4 5 7 9 4
[[3]]
[1] 10 10 10
> word <- function(C, k) paste(rep(C, times = k), collapse = "")
> mapply(word, C=LETTERS[1:6], k=6:1, SIMPLIFY = T)
A B C D E F
"AAAAAA" "BBBBB" "CCCC" "DDD" "EE" "F"
There are cases when lapply doesnโt work fine. Using rapply we can specify a function to operate only in a specific class -
> list1 <- list(matrix1 = matrix(5:8,nrow=2,ncol=2),
+ matrix2 = matrix(1:16, nrow = 4, ncol = 4),
+ character = "sample one",
+ a_df = data.frame(X = c(1,2,3), Y = c(12,13,10))
+ )
> rapply(list1, nchar, "character")
character
10
Unlist is default argument for how -
> rapply(list1, diag, "array", how = "unlist")
matrix11 matrix12 matrix21 matrix22 matrix23 matrix24
5 8 1 6 11 16
Using list, we can get a similar output like lapply -
> rapply(list1, diag, "array", how = "list")
$matrix1
[1] 5 8
$matrix2
[1] 1 6 11 16
$character
NULL
$a_df
$a_df$X
NULL
$a_df$Y
NULL
Replacing the output to the supplied object -
> rapply(list1, diag, "array", how = "replace")
$matrix1
[1] 5 8
$matrix2
[1] 1 6 11 16
$character
[1] "sample one"
$a_df
X Y
1 1 12
2 2 13
3 3 10
We can apply a function to any types of object by default -
> rapply(list1, is.matrix, classes = "ANY")
matrix1 matrix2 character a_df.X a_df.Y
TRUE TRUE FALSE FALSE FALSE
Repeat does the work of repeating of a program until the execution of break command -
> counter <- 0
> repeat{
+ counter <- counter + 1
+ print(paste("Repeating line",counter))
+ if(counter >=10) break
+ }
[1] "Repeating line 1"
[1] "Repeating line 2"
[1] "Repeating line 3"
[1] "Repeating line 4"
[1] "Repeating line 5"
[1] "Repeating line 6"
[1] "Repeating line 7"
[1] "Repeating line 8"
[1] "Repeating line 9"
[1] "Repeating line 10"
Example with next and break -
> counter <- 0
> repeat{
+ counter <- counter + 1
+ if (counter < 5){
+ print("Going to step")
+ next
+ # this next will take the code to the next loop
+ print(counter) # this won't execute because next has already been executed
+ }else if(counter > 10) {
+ print("Executing break")
+ break
+ # this break statemend will kill the loop
+ }else{
+ print(counter)
+ }
+ }
[1] "Going to step"
[1] "Going to step"
[1] "Going to step"
[1] "Going to step"
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10
[1] "Executing break"
This is an example of repeat-
> num1 <- 1
> num2 <- 1
> n <- 1000
> cat("== Showing Fibonacci numbers upto",n,"==\n")
== Showing Fibonacci numbers upto 1000 ==
> repeat{
+ feb <- num1+num2
+ if (feb>=n){
+ cat("break executed...")
+ break
+ }
+ num1 <- num2
+ num2 <- feb
+ cat(feb," ")
+
+ }
2 3 5 8 13 21 34 55 89 144 233 377 610 987 break executed...
The repetition continues until the execution of any break statement.
Returns a list splitting the observations of a vector x(or data frame) according to given f -
> df <- data.frame(gender = c(rep("boy",3),
+ rep("girl",4),
+ rep("unknown",2)),
+ freq = c(7,7,1,6,5,2,4,8,9))
> split(x = df$freq, f = df$gender)
$boy
[1] 7 7 1
$girl
[1] 6 5 2 4
$unknown
[1] 8 9
So it basically loops through the vectors pairwise and assigns elements of x to respective f in list, which comes handy in some cases.