Exercícios


Códigos importantes cap. 10


Function/operator Brief description
if( ){ } Conditional check
if( ){ } else { } Check and alternative
ifelse Element-wise if-else check
switch Multiple if choices
for( ){ } Iterative loop
while( ){ } Conditional loop
apply Implicit loop by margin
tapply Implicit loop by factor
lapply Implicit loop by member
sapply As lapply, array returned
break Exit explicit loop Section
next Skip to next loop iteration
repeat{ } Repeat code until break


Seção 10.1


Item a

Crie os seguintes vetores:

vec1 <- c(2,1,1,3,2,1,0) vec2 <- c(3,8,2,2,0,0,0)

Sem executá-los, determine qual dos seguintes if statements resultariam em um string sendo impresso no console. Em seguinda, confirme suas respostas.

  1. if((vec1[1]+vec2[2])==10){ cat(“Print me!”) } - só verifica o primeiro elemento, que é igual a 10 e portanto imprime;
  2. if(vec1[1]>=2&&vec2[1]>=2){ cat(“Print me!”) } - ambas as condições são satisfeitas, imprime o texto;
  3. if(all((vec2-vec1)[c(2,6)]<7)){ cat(“Print me!”) } - este if só avalia o primeiro termo, que é igual a 7 e portanto nao imprime;
  4. if(!is.na(vec2[3])){ cat(“Print me!”) } - imprime, pois vec2[3] não é NA.
vec1 <- c(2,1,1,3,2,1,0)
vec2 <- c(3,8,2,2,0,0,0)

if((vec1[1]+vec2[2])==10){ cat("Print me!") }
## Print me!
if(vec1[1]>=2&&vec2[1]>=2){ cat("Print me!") }
## Print me!
if(all((vec2-vec1)[c(2,6)]<7)){ cat("Print me!") } #não imprime

if(!is.na(vec2[3])){ cat("Print me!") }
## Print me!


Item b

Usando os mesmos vetores, escreva e execute a linha de código que multiplica os elementos correspondentes dos dois vetores se sua soma for maior que 3. Caso contrário, o código deve simplesmente somar os elementos.

vec3 <- (vec1+vec2) >=3

ifelse(vec3 == 1, vec1*vec2, vec1+vec2)
## [1] 6 8 2 6 2 1 0


Item c

No editor, escreva código que tome uma matriz quadrada de caracteres e checa se qualquer dos strings na diagonal principal começam com a letra g, maiúscula ou minúscula. Se satisfeito, essas entradas devem ser sobrescritas com “HERE”. Caso contrário, a matriz inteira deve ser substituída com uma matriz identidade com as mesmas dimensões.

acha_g <- function(x){
  #identifica se existe um g
  test <- ifelse(grepl(pattern = "^g|G",diag(x)) == TRUE, "HERE", diag(x))
  #se sim, o elemento 'e substituido por here
  if("HERE" %in% test){
    diag(x) <- test
    return(x)
    # caso contrario, matriz identidade
  }else{
    return(diag(dim(x)[1]))}
  }

#i
mymat <- matrix(as.character(1:16),4,4)

acha_g(mymat)
##      [,1] [,2] [,3] [,4]
## [1,]    1    0    0    0
## [2,]    0    1    0    0
## [3,]    0    0    1    0
## [4,]    0    0    0    1
#ii

mymat <- matrix(c("DANDELION","Hyacinthus","Gerbera",
"MARIGOLD","geranium","ligularia",
"Pachysandra","SNAPDRAGON","GLADIOLUS"),3,3)

acha_g(mymat)
##      [,1]         [,2]        [,3]         
## [1,] "DANDELION"  "MARIGOLD"  "Pachysandra"
## [2,] "Hyacinthus" "HERE"      "SNAPDRAGON" 
## [3,] "Gerbera"    "ligularia" "HERE"
#iii

mymat <- matrix(c("GREAT","exercises","right","here"),2,2,
byrow=T)

acha_g(mymat)
##      [,1]    [,2]       
## [1,] "HERE"  "exercises"
## [2,] "right" "here"



Início



Seção 10.2


Item a

Condições if empilhadas que realizem o mesmo que o switch a seguir:

R> mynum <- 3

R> foo <- switch(mynum,12,34,56,78,NA

R> foo

[1] 56

stack <- function(x){
  if (x == 1) {foo <<- 12 # <<- operador para atingir variável do escopo global
  } else if (x == 2) {foo <<- 34
  } else if (x == 3) {foo <<- 56
  } else if (x == 4) {foo <<- 78
  } else if (x == 5) {foo <<- NA
  } else {foo <<- NULL}
  print(foo)
}

mynum <- 3
stack(mynum)
## [1] 56
stack(0) # equivalente a mynum <- 0
## NULL


Item b

#define a funcao
condicionais <- function(){

if ("High" %in% doselevel){

  if (lowdose >= 10){ lowdose <- 10
  } else {lowdose <- lowdose/2}

  if (meddose >= 26) { meddose <- 26 }

  if (highdose < 60) { highdose <- 60 } else {highdose <- highdose *1.5}

  dosage <<- c(rep(lowdose, length(doselevel)))

  dosage[which(doselevel == "Med")] <<- meddose

  dosage[which(doselevel == "High")] <<- highdose
  
  
} else {
  
  doselevel <<- factor(doselevel, levels = c("Low", "Med"), labels = c("Small", "Large"))

  if (lowdose < 15 & meddose < 35) {
    lowdose <- lowdose*2
    meddose <- meddose + highdose}

  dosage <<- c(rep(lowdose, length(doselevel)))

  dosage[which(doselevel == "Large")] <<- meddose
  
  
  }
}


#i
lowdose <- 12.5
meddose <- 25.3
highdose <- 58.1
doselevel <- factor(c("Low","High","High","High","Low","Med",
"Med"),levels=c("Low","Med","High"))

condicionais()
  
dosage
## [1] 10.0 60.0 60.0 60.0 10.0 25.3 25.3
#ii
lowdose <- 12.5
meddose <- 25.3
highdose <- 58.1
doselevel <- factor(c("Low","Low","Low","Med","Low","Med",
"Med"),levels=c("Low","Med","High"))

condicionais()

dosage
## [1] 25.0 25.0 25.0 83.4 25.0 83.4 83.4
doselevel
## [1] Small Small Small Large Small Large Large
## Levels: Small Large
#iii

lowdose <- 9
meddose <- 49
highdose <- 61
doselevel <- factor(c("Low","Med","Med"),
levels=c("Low","Med","High"))

condicionais()

dosage
## [1]  9 49 49
doselevel
## [1] Small Large Large
## Levels: Small Large
#iv
lowdose <- 9
meddose <- 49
highdose <- 61

doselevel <- factor(c("Low","High","High","High","Low","Med",
"Med"),levels=c("Low","Med","High"))

condicionais()
  
dosage
## [1]  4.5 91.5 91.5 91.5  4.5 26.0 26.0


Item c

mynum <- sample(0:9, size = 1)

switcharoo <- function(x){
  switch(x+1, 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine') %>%
    print()
}

for (i in 1:5) { 
  mynum <- sample(0:9, size = 1)
  print(mynum)
  switcharoo(mynum)
}
## [1] 0
## [1] "zero"
## [1] 1
## [1] "one"
## [1] 8
## [1] "eight"
## [1] 8
## [1] "eight"
## [1] 9
## [1] "nine"



Início



Seção 10.3


Item a

loopvec1 <- 5:7
loopvec2 <- 9:6
foo <- matrix(NA,length(loopvec1),length(loopvec2))

for(i in 1:length(loopvec1)){
    foo[i,] <- loopvec1[i]*loopvec2
}

foo
##      [,1] [,2] [,3] [,4]
## [1,]   45   40   35   30
## [2,]   54   48   42   36
## [3,]   63   56   49   42


Item b

# switch(EXPR=mystring,Homer=12,Marge=34,Bart=56,Lisa=78,Maggie=90,
# NA)

vec <- c("Peter","Homer","Lois","Stewie","Maggie","Bart")

vec_int <- NA

for (i in 1:length(vec)){
  vec_int[i] <- switch(EXPR=vec[i],Homer=12,Marge=34,Bart=56,Lisa=78,Maggie=90,
NA)
}

vec_int
## [1] NA 12 NA NA 90 56


Item c

contador <- function(list){
  counter <- 0
  
  for (i in 1:length(list)){ #itera sobre os itens da lista principal
    
    member <- list[[i]] #toma como member o elemento i da lista principal
    
    if (is.matrix(member)){ #incrementa se o elemento for uma matriz
      counter <- counter+1
    }
    
    if (is.list(member)){ #itera sobre os elementos da lista principal que
                          #sao listas
      for (j in 1:length(member)){
        if(is.matrix(member[[j]])){
          counter <- counter+1
        }
      }
    }
  } 
  return(counter)
}

#i
mylist <- list(aa=c(3.4,1),bb=matrix(1:4,2,2),
cc=matrix(c(T,T,F,T,F,F),3,2),dd="string here",
ee=list(c("hello","you"),matrix(c("hello",
"there"))),
ff=matrix(c("red","green","blue","yellow")))

contador(mylist)
## [1] 4
#ii
mylist <- list("tricked you",as.vector(matrix(1:6,3,2)))

contador(mylist)
## [1] 0
#iii
mylist <- list(list(1,2,3),list(c(3,2),2),
list(c(1,2),matrix(c(1,2))),
rbind(1:10,100:91))

contador(mylist)
## [1] 2



Início



Seção 10.4


Item a

mylist <- list()
counter <- 1
mynumbers <- c(4,5,1,2,6,2,4,6,6,2)
mycondition <- mynumbers[counter]<=5

while(mycondition){
  
  mylist[[counter]] <- diag(mynumbers[counter])
  counter <- counter+1
  if(counter<=length(mynumbers)){
    mycondition <- mynumbers[counter]<=5
    } else {
    mycondition <- FALSE
  }
}

# i. deve imprimir todas as matrizes ja que todos os elementos sao <= 5
mynumbers <- c(2,2,2,2,5,2)
mylist <- list()
counter <- 1
mycondition <- mynumbers[counter]<=5

while(mycondition){
  
  mylist[[counter]] <- diag(mynumbers[counter])
  counter <- counter+1
  if(counter<=length(mynumbers)){
    mycondition <- mynumbers[counter]<=5
    } else {
    mycondition <- FALSE
  }
}
mylist
## [[1]]
##      [,1] [,2]
## [1,]    1    0
## [2,]    0    1
## 
## [[2]]
##      [,1] [,2]
## [1,]    1    0
## [2,]    0    1
## 
## [[3]]
##      [,1] [,2]
## [1,]    1    0
## [2,]    0    1
## 
## [[4]]
##      [,1] [,2]
## [1,]    1    0
## [2,]    0    1
## 
## [[5]]
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    0    0    0    0
## [2,]    0    1    0    0    0
## [3,]    0    0    1    0    0
## [4,]    0    0    0    1    0
## [5,]    0    0    0    0    1
## 
## [[6]]
##      [,1] [,2]
## [1,]    1    0
## [2,]    0    1
# ii. # deve imprimir até o elemento de valor 5
mynumbers <- 2:20
mylist <- list()
counter <- 1
mycondition <- mynumbers[counter]<=5

while(mycondition){
  
  mylist[[counter]] <- diag(mynumbers[counter])
  counter <- counter+1
  if(counter<=length(mynumbers)){
    mycondition <- mynumbers[counter]<=5
    } else {
    mycondition <- FALSE
  }
}
mylist
## [[1]]
##      [,1] [,2]
## [1,]    1    0
## [2,]    0    1
## 
## [[2]]
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    1    0
## [3,]    0    0    1
## 
## [[3]]
##      [,1] [,2] [,3] [,4]
## [1,]    1    0    0    0
## [2,]    0    1    0    0
## [3,]    0    0    1    0
## [4,]    0    0    0    1
## 
## [[4]]
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    0    0    0    0
## [2,]    0    1    0    0    0
## [3,]    0    0    1    0    0
## [4,]    0    0    0    1    0
## [5,]    0    0    0    0    1
# iii. #nao deve imprimir nada
mynumbers <- c(10,1,10,1,2)
mylist <- list()
counter <- 1
mycondition <- mynumbers[counter]<=5

while(mycondition){
  
  mylist[[counter]] <- diag(mynumbers[counter])
  counter <- counter+1
  if(counter<=length(mynumbers)){
    mycondition <- mynumbers[counter]<=5
    } else {
    mycondition <- FALSE
  }
}
mylist
## list()


Item b

fact_while <- function(mynum){
  
  if(mynum == 0){mynum <- 1
  } else {
    mynum <- mynum
    counter <-mynum-1
    
    while(counter >= 0){
      mynum <- mynum*counter
      counter <- counter-1
      if(counter == 0){break}
    }
  }
  return(mynum)
}

fact_while(5)
## [1] 120
fact_while(12)
## [1] 479001600
fact_while(0)
## [1] 1


Item c

mystring <- "R fever"
index <- 1
ecount <- 0
result <- mystring

while(ecount<2 && index<=nchar(mystring)){
  char <- substr(mystring, index, index)
  
  if(char == "E" | char == "e"){
    ecount <- ecount+1
  }
  
  if(ecount >= 2){
    result <- substr(mystring, 0, index-1)
    break
  }
  

  index <- index+1
  
  result <- substr(mystring, 0, index-1)

}
result
## [1] "R fev"
#i
mystring <- "beautiful"
index <- 1
ecount <- 0
result <- mystring

while(ecount<2 && index<=nchar(mystring)){
  char <- substr(mystring, index, index)
  
  if(char == "E" | char == "e"){
    ecount <- ecount+1
  }
  
  if(ecount >= 2){
    result <- substr(mystring, 0, index-1)
    break
  }
  

  index <- index+1
  
  result <- substr(mystring, 0, index-1)

}
result
## [1] "beautiful"
#ii
mystring <- "ECCENTRIC"
index <- 1
ecount <- 0
result <- mystring

while(ecount<2 && index<=nchar(mystring)){
  char <- substr(mystring, index, index)
  
  if(char == "E" | char == "e"){
    ecount <- ecount+1
  }
  
  if(ecount >= 2){
    result <- substr(mystring, 0, index-1)
    break
  }
  

  index <- index+1
  
  result <- substr(mystring, 0, index-1)

}
result
## [1] "ECC"
#iii
mystring <- "ElAbOrAte"
index <- 1
ecount <- 0
result <- mystring

while(ecount<2 && index<=nchar(mystring)){
  char <- substr(mystring, index, index)
  
  if(char == "E" | char == "e"){
    ecount <- ecount+1
  }
  
  if(ecount >= 2){
    result <- substr(mystring, 0, index-1)
    break
  }
  

  index <- index+1
  
  result <- substr(mystring, 0, index-1)

}
result
## [1] "ElAbOrAt"
#iv
mystring <-"eeeeek!"
index <- 1
ecount <- 0
result <- mystring

while(ecount<2 && index<=nchar(mystring)){
  char <- substr(mystring, index, index)
  
  if(char == "E" | char == "e"){
    ecount <- ecount+1
  }
  
  if(ecount >= 2){
    result <- substr(mystring, 0, index-1)
    break
  }
  

  index <- index+1
  
  result <- substr(mystring, 0, index-1)

}
result
## [1] "e"



Início



Seção 10.5


Implicit looping

apply() - apply a function over a dimension

tapply() - apply a function factoring by a factor variable. Ex: sum of values for different types of a product.

lapply() - apply a function over elements of a list

sapply() - returns lapply() in array form

Arguments of the function applied can be passed as arguments in the ellipses of the apply family.


Item a

foo <- matrix(1:12,4,3)

foo <- apply(foo,1,sort,decreasing=TRUE)

apply(foo, 2, sum) #soma das colunas, indicando colunas no segundo argumento
## [1] 15 18 21 24


Item b

matlist <- list(matrix(c(T,F,T,T),2,2),
                matrix(c("a","c","b","z","p","q"),3,2),
                matrix(1:8,2,4))

matlist # cria 3 matrizes: lógica 2x2, caracteres 3x2, numérica 2x4 
## [[1]]
##       [,1] [,2]
## [1,]  TRUE TRUE
## [2,] FALSE TRUE
## 
## [[2]]
##      [,1] [,2]
## [1,] "a"  "z" 
## [2,] "c"  "p" 
## [3,] "b"  "q" 
## 
## [[3]]
##      [,1] [,2] [,3] [,4]
## [1,]    1    3    5    7
## [2,]    2    4    6    8
for(i in 1:length(matlist)){ #loop transpõe cada matriz na lista
  
  matlist[[i]] <- t(matlist[[i]])
}

matlist
## [[1]]
##      [,1]  [,2]
## [1,] TRUE FALSE
## [2,] TRUE  TRUE
## 
## [[2]]
##      [,1] [,2] [,3]
## [1,] "a"  "c"  "b" 
## [2,] "z"  "p"  "q" 
## 
## [[3]]
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
## [3,]    5    6
## [4,]    7    8
#resetando a lista
matlist <- list(matrix(c(T,F,T,T),2,2),
                matrix(c("a","c","b","z","p","q"),3,2),
                matrix(1:8,2,4))

lapply(matlist, t) #aplicar funcao t a cada elemento de matlist
## [[1]]
##      [,1]  [,2]
## [1,] TRUE FALSE
## [2,] TRUE  TRUE
## 
## [[2]]
##      [,1] [,2] [,3]
## [1,] "a"  "c"  "b" 
## [2,] "z"  "p"  "q" 
## 
## [[3]]
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
## [3,]    5    6
## [4,]    7    8


Item c

qux <- array(96:1,dim=c(4,4,2,3))
# 3 blocos formados de 2 camadas de matrizes 4x4


#i elementos diagonais de todas as matrizes da secunda camada
apply(qux[,,2,], MARGIN = 3, FUN = diag)
##      [,1] [,2] [,3]
## [1,]   80   48   16
## [2,]   75   43   11
## [3,]   70   38    6
## [4,]   65   33    1
#ii 
apply(qux[,4,,], MARGIN = 3, dim) %>% #aplica dim() à quarta coluna, por camada resultante do subset qu[,4,,]
  apply(MARGIN = 1, sum) #aplica soma por linha
## [1] 12  6



Início



Seção 10.6


next indica que, sob uma determinada condição, o laço deve pular aquela iteração. Está limitado ao escopo da iteração. Por exemplo, se ocorrer em uma iteração aninhada, só pularia uma das subiterações sem comprometer a iteração de escopo superior.

break indica uma parada do processo geral de iteração.

repeat{} é um laço while implícito, que executa iterações dentro das chaves {} até que seja dada uma instrução de interrupção com break


Item a

foo <- 5
bar <- c(2,3,1.1,4,0,4.1,3)

# laço while deve produzir loop2.result == 2.500000 1.666667 4.545455 1.250000 NA NA NA

loop2.result <- rep(NA,length(bar))

counter <- 1
mycondition <- (foo/bar)!= Inf

while(mycondition[counter]){
  loop2.result[counter] <- (foo/bar)[counter]
  counter <- counter+1
}

loop2.result
## [1] 2.500000 1.666667 4.545455 1.250000       NA       NA       NA


Item b

#i
mynumbers <- c(4,5,1,2,6,2,4,6,6,2)

mylist <- list()

for (i in 1:length(mynumbers)){
  
  if (mynumbers[i] <= 5){
    mylist[[i]] <- diag(mynumbers[i])
  } else{break}  
}

mylist
## [[1]]
##      [,1] [,2] [,3] [,4]
## [1,]    1    0    0    0
## [2,]    0    1    0    0
## [3,]    0    0    1    0
## [4,]    0    0    0    1
## 
## [[2]]
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    0    0    0    0
## [2,]    0    1    0    0    0
## [3,]    0    0    1    0    0
## [4,]    0    0    0    1    0
## [5,]    0    0    0    0    1
## 
## [[3]]
##      [,1]
## [1,]    1
## 
## [[4]]
##      [,1] [,2]
## [1,]    1    0
## [2,]    0    1
#ii
mylist <- list()
counter <- 1

repeat{
  mylist[[counter]] <- diag(mynumbers[counter])
  counter <- counter+1
  if(mynumbers[counter] > 5){break}
}

mylist
## [[1]]
##      [,1] [,2] [,3] [,4]
## [1,]    1    0    0    0
## [2,]    0    1    0    0
## [3,]    0    0    1    0
## [4,]    0    0    0    1
## 
## [[2]]
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    0    0    0    0
## [2,]    0    1    0    0    0
## [3,]    0    0    1    0    0
## [4,]    0    0    0    1    0
## [5,]    0    0    0    0    1
## 
## [[3]]
##      [,1]
## [1,]    1
## 
## [[4]]
##      [,1] [,2]
## [1,]    1    0
## [2,]    0    1


Item c

#i
reslist <- list()
matlist1 <- list(matrix(1:4,2,2),matrix(1:4),matrix(1:8,4,2))
matlist2 <- matlist1

counter <- 1
for (i in 1:length(matlist1)){
  for (j in 1:length(matlist2)){
    
    if(ncol(matlist1[[i]]) == nrow(matlist2[[j]])){
        
      reslist[[counter]] <- matlist1[[i]] %*% matlist2[[j]]
      counter <- counter+1
      
    } else {
      reslist[[counter]] <- "not possible"
      counter <- counter+1
    }
  }
}
reslist
## [[1]]
##      [,1] [,2]
## [1,]    7   15
## [2,]   10   22
## 
## [[2]]
## [1] "not possible"
## 
## [[3]]
## [1] "not possible"
## 
## [[4]]
## [1] "not possible"
## 
## [[5]]
## [1] "not possible"
## 
## [[6]]
## [1] "not possible"
## 
## [[7]]
##      [,1] [,2]
## [1,]   11   23
## [2,]   14   30
## [3,]   17   37
## [4,]   20   44
## 
## [[8]]
## [1] "not possible"
## 
## [[9]]
## [1] "not possible"
#ii
reslist <- list()
matlist1 <- list(matrix(1:4,2,2),matrix(2:5,2,2),matrix(1:16,4,2))
matlist2 <- list(matrix(1:8,2,4),matrix(10:7,2,2),matrix(9:2,4,2))

counter <- 1
for (i in 1:length(matlist1)){
  for (j in 1:length(matlist2)){
    
    if(ncol(matlist1[[i]]) == nrow(matlist2[[j]])){
        
      reslist[[counter]] <- matlist1[[i]] %*% matlist2[[j]]
      counter <- counter+1
      
    } else {
      reslist[[counter]] <- "not possible"
      counter <- counter+1
    }
  }
}
reslist
## [[1]]
##      [,1] [,2] [,3] [,4]
## [1,]    7   15   23   31
## [2,]   10   22   34   46
## 
## [[2]]
##      [,1] [,2]
## [1,]   37   29
## [2,]   56   44
## 
## [[3]]
## [1] "not possible"
## 
## [[4]]
##      [,1] [,2] [,3] [,4]
## [1,]   10   22   34   46
## [2,]   13   29   45   61
## 
## [[5]]
##      [,1] [,2]
## [1,]   56   44
## [2,]   75   59
## 
## [[6]]
## [1] "not possible"
## 
## [[7]]
##      [,1] [,2] [,3] [,4]
## [1,]   11   23   35   47
## [2,]   14   30   46   62
## [3,]   17   37   57   77
## [4,]   20   44   68   92
## 
## [[8]]
##      [,1] [,2]
## [1,]   55   43
## [2,]   74   58
## [3,]   93   73
## [4,]  112   88
## 
## [[9]]
## [1] "not possible"



Início