Esse material foi elaborado para o Treinamento em Programação no Ambiente R organizado pelo Laboratório de Genetica Estatistica do Departamento de Genética da ESALQ- USP

Sugerimos que, antes de iniciar a prática aqui descrita, siga este tutorial para instalação do R e do RStudio.

Familiarização com a interface do RStudio

Abrindo o RStudio você verá:

A interface é separada em quatro janelas com principais funções:

  • Edição de código
  • Ambiente de trabalho e histórico
  • Console
  • Arquivos, gráficos, pacotes e ajuda

Explore cada uma das janelas. São inúmeras funcionalidades para cada uma delas, veremos algumas delas ao decorrer do curso.

Um primeiro script

A janela de edição de código (provavelmente localizada no canto superior esquerdo) você irá utilizar para escrever o seu código. Abra um novo script clicando no + no canto superior esquerdo e selecionando R script.

Vamos então iniciar os trabalhos com o tradicional Hello World. Digite no seu script:

cat("Hello world")
## Hello world

Agora, selecione a linha e aperte o botão Run ou utilize Ctrl + enter.

Ao fazer isso o seu código será processado na janela Console, onde aparecerá em azul (se você estiver com as cores padrão do R) o código escrito e, logo em seguida, o resultado desejado. A linha somente não será processada no console se houver o símbolo # na frente. Agora, experimente colocar # na frente do código escrito. E, novamente, selecione a linha e aperte Run.

# cat("Hello world")

O símbolo # é muito utilizado para realizar comentários ao decorrer do código. Esta é uma ótima prática para deixar o código organizado e para que você possa lembrar mais tarde o que você estava pensando quando o escreveu ou para que outras pessoas possam entendê-lo. Como no exemplo:

# Iniciando os trabalhos no R
cat("Hello world")
## Hello world

Importante: sempre que quiser realizar alguma alteração, edite o seu script e não diretamente no console, pois tudo o que neste é escrito, não terá como ser salvo!

Para salvar seu script, você pode utilizar a aba Files localizada (como padrão) no canto direito inferior para procurar uma localização de sua preferência, criar uma nova pasta com o nome CursoR.

Dica:

  • Evite colocar espaços e pontuações no nome das pastas e arquivos, isso pode dificultar o acesso via linha de comando no R. Por exemplo, ao invés de Curso R, optamos por CursoR.

Depois, basta clicar no disquete localizado no cabeçalho do RStudio ou com Ctrl + s e selecionar o diretório CursoR criado. Scripts em R são salvos com a extensão .R.

Estabelecendo diretório de trabalho

Outra boa prática no R é deixar o script no mesmo diretório onde estão seus dados brutos (arquivos de entrada no script) e os dados processados (gráficos, tabelas, etc). Para isso, vamos fazer com que o R identifique o mesmo diretório em que você salvou o script como diretório de trabalho, assim ele entenderá que é dali que precisa obter os dados e para lá que também irão os resultados.

Você pode fazer isso utilizando as facilidades do RStudio, basta localizar o diretório CursoR pela aba Files, clicar em More e depois “Set as Working Directory”. Repare que irá aparecer no console algo como:

setwd("~/Documents/CursoR")

Ou seja, você pode utilizar este mesmo comando para realizar esta ação. Esta então será nossa pasta de trabalho. Quando estiver perdido/a ou para ter certeza que o diretório de trabalho foi alterado utilize:

getwd()

Facilitando a vida com Tab

Agora, imagine que você tem um diretório como ~/Documentos/mestrado/semestre1/disciplina_tal/aula_tal/dados_28174/analise_276182/resultados_161/. Não é fácil lembrar todo este caminho para escrever num comando setwd().

Além da facilidade da janela do RStudio, você pode utilizar a tecla Tab para completar o caminho para você. Experimente buscando alguma pasta no seu computador. Basta começar a digitar o caminho e apertar Tab, ele irá completar o nome para você! Se você tiver mais do que um arquivo com aquele início de nome, aperte duas vezes o Tab, ele mostrará todas as opções.

O Tab funciona não só para indicar caminhos, mas também para comandos e nomes de objetos. É muito comum errarmos no código por erros de digitação. Utilizar o Tab reduzirá significativamente esses erros.

Operações básicas

Vamos então à linguagem!

O R pode funcionar como uma simples calculadora, que utiliza a mesma sintaxe que outros programas (como o excel):

1+1.3                 #Decimal definido com "."
2*3
2^3
4/2

sqrt(4)              #raíz quadrada
log(100, base = 10)  #logarítmo na base 10
log(100)             #logarítmo com base neperiana

Agora, utilize as operações básicas para solucionar expressão abaixo. Lembre-se de utilizar parênteses () para estabelecer prioridades nas operações.

\((\frac{13+2+1.5}{3})+ log_{4}96\)

Resultado esperado:

## [1] 8.792481

Repare que, se posicionar o parênteses de forma incorreta, o código não resultará em nenhuma mensagem de erro, pois este é um erro que chamamos de erro lógico, ou seja, o código roda, mas não faz o que você gostaria que ele fizesse. Esse é o tipo de erro mais difícil de ser consertado. Os erros que produzem uma mensagem, seja um aviso (warning) ou um erro (error) são chamados de erros de sintaxe. Nesses casos, o R retornará uma mensagem para te ajudar a corrigí-los. Os warnings não comprometem o funcionamento do código, mas chamam a atenção para algum ponto, já os errors precisam necessariamente ser corrigidos para que o código rode.

Exemplo de error:

((13+2+1,5)/3) + log(96, base = 4)

Você pode também esquecer de fechar algum parênteses, ou aspas, ou colchetes, ou chaves, nesses casos, o R ficará aguardando o comando para fechar o bloco de código sinalizando com um +:

((13+2+1.5)/3 + log(96, base = 4)

Se acontecer, vá até o console e aperte ESC, que o bloco será finalizado para que você possa corrigí-lo.

Os comandos log e sqrt são duas de muitas outras funções básicas que o R possui. Funções são conjuntos de instruções organizadas para realizar uma tarefa. Para todas elas, o R possui uma descrição para auxiliar no seu uso, para acessar essa ajuda use:

?log

E será aberta a descrição da função na janela Help do RStudio.

Se a descrição do próprio R não for suficiente para você entender como funciona a função, busque no google (de preferência em inglês). Existem diversos sites e fóruns com informações didáticas das funções do R.

Operações com vetores

Os vetores são as estruturas mais simples trabalhadas no R. Construímos um vetor com uma sequencia numérica usando:

c(1,3,2,5,2)
## [1] 1 3 2 5 2

MUITA ATENÇÃO: O c é a função do R (Combine Values into a Vector or List) com a qual construímos um vetor!

Utilizamos o simbolo : para criar sequências de números inteiros, como:

1:10
##  [1]  1  2  3  4  5  6  7  8  9 10

Podemos utilizar outras funções para gerar sequências, como:

seq(from=0, to=100, by=5)
##  [1]   0   5  10  15  20  25  30  35  40  45  50  55  60  65  70  75  80  85  90
## [20]  95 100
# ou
seq(0,100,5) # Se você já souber a ordem dos argumentos da função
##  [1]   0   5  10  15  20  25  30  35  40  45  50  55  60  65  70  75  80  85  90
## [20]  95 100
  • Crie uma sequencia utilizando a função seq que varie de 4 a 30, com intervalos de 3 em 3.
## [1]  4  7 10 13 16 19 22 25 28

A função rep gera sequências com números repetidos:

rep(3:5, 2)
## [1] 3 4 5 3 4 5

Podemos realizar operações utilizando esses vetores:

c(1,4,3,2)*2
c(4,2,1,5)+c(5,2,6,1)
c(4,2,1,5)*c(5,2,6,1)

Repare que já esta ficando cansativo digitar os mesmos números repetidamente, vamos resolver isso criando objetos para armazenar nossos vetores e muito mais.

Criando objetos

O armazenamento de informações em objetos e a possível manipulação desses faz do R uma linguagem orientada por objetos. Para criar um objeto basta atribuir valores para as variáveis, como a seguir:

x = c(30.1,30.4,40,30.2,30.6,40.1)
# ou
x <- c(30.1,30.4,40,30.2,30.6,40.1)

y = c(0.26,0.3,0.36,0.24,0.27,0.35)

Os mais antigos costumam usar o sinal <-, mas tem a mesma função de =. Há quem prefira usar o <- como atribuição em objetos e = apenas para definir os argumentos dentro de funções. Organize-se da forma como preferir.

Para acessar os valores dentro do objeto basta:

x
## [1] 30.1 30.4 40.0 30.2 30.6 40.1

A linguagem é sensível à letras maiúsculas e minúsculas, portanto x é diferente de X:

X

O objeto X não foi criado.

O nome dos objetos é uma escolha pessoal, a sugestão é tentar manter um padrão para melhor organização. Alguns nomes não podem ser usados por estabelecerem papéis fixos no R, são eles:

  • NA - Not available, simboliza dados faltantes
  • NaN - Not a number, simboliza indefinições matemáticas
  • Inf - Infinite, conceito matemático
  • NULL - Null object, simboliza ausência de informação

Podemos então realizar as operações com o objeto criado:

Para realizar a operação o R alinha os dois vetores e realiza a operação elemento à elemento. Observe:

x + y
## [1] 30.36 30.70 40.36 30.44 30.87 40.45
x*y
## [1]  7.826  9.120 14.400  7.248  8.262 14.035

Se os vetores tiverem tamanhos diferentes, ele irá repetir o menor para realizar a operação elemento à elemento com todos do maior.

x*2
x*c(1,2)

Se caso o menor vetor não for múltiplo do maior, obteremos um aviso:

x*c(1,2,3,4)
## Warning in x * c(1, 2, 3, 4): longer object length is not a multiple of shorter
## object length
## [1]  30.1  60.8 120.0 120.8  30.6  80.2

Repare que o warning não compromente o funcionamento do código, ele só dá uma dica de que algo pode não estar da forma como você gostaria.

Podemos também armazenar a operação em outro objeto:

z <- (x+y)/2
z

Podemos também aplicar algumas funções, como exemplo:

sum(z)  # soma dos valores de z
## [1] 101.59
mean(z) # média 
## [1] 16.93167
var(z)  # variância
## [1] 6.427507

Indexação

Acessamos somente o 3º valor do vetor criado com []:

z[3]

Também podemos acessar o número da posição 2 a 4 com:

z[2:4]
## [1] 15.35 20.18 15.22

Para obter informações do vetor criado utilize:

str(z)
##  num [1:6] 15.2 15.3 20.2 15.2 15.4 ...

A função str nos diz sobre a estrutura do vetor, que se trata de um vetor numérico com 6 elementos.

Os vetores também podem receber outras categorias como caracteres:

clone <- c("GRA02", "URO01", "URO03", "GRA02", "GRA01", "URO01")

Outra classe são os fatores, esses podem ser um pouco complexos de lidar.

De forma geral, fatores são valores categorizados por levels, como exemplo, se transformarmos nosso vetor de caracteres clone em fator, serão atribuidos níveis para cada uma das palavras:

clone_fator <- as.factor(clone)
str(clone_fator)
##  Factor w/ 4 levels "GRA01","GRA02",..: 2 3 4 2 1 3
levels(clone_fator)
## [1] "GRA01" "GRA02" "URO01" "URO03"

Dessa forma, teremos apenas 4 níveis para um vetor com 6 elementos, já que as palavras “GRA02” e “URO01” se repetem. Podemos obter o número de elementos do vetor ou o seu comprimento com:

length(clone_fator)
## [1] 6

Também há vetores lógicos, que recebem valores de verdadeiro ou falso:

logico <- x > 40
logico   # Os elementos são maiores que 40?
## [1] FALSE FALSE FALSE FALSE FALSE  TRUE

Com ele podemos, por exemplo, identificar quais são as posições dos elementos maiores que 40:

which(logico)  # Obtendo as posiçoes dos elementos TRUE
## [1] 6
x[which(logico)] # Obtendo os números maiores que 40 do vetor x pela posição
## [1] 40.1
# ou
x[which(x > 40)]
## [1] 40.1

Também podemos localizar elementos específicos com:

clone %in% c("URO03", "GRA02")
## [1]  TRUE FALSE  TRUE  TRUE FALSE FALSE

Também podem ser úteis as funções any e all. Procure sobre elas.

Encontre mais sobre outros operadores lógicos, como o > utilizado, neste link.

Warning1

Faça uma sequência numérica, contendo 10 valores inteiros, e salve em um objeto chamado “a”.

(a <- 1:10)
##  [1]  1  2  3  4  5  6  7  8  9 10

Crie outra sequência, utilizando números decimais e qualquer operação matemática, de tal forma que seus valores sejam idênticos ao objeto “a”.

b <- seq(from = 0.1, to = 1, 0.1)
(b <- b*10)
##  [1]  1  2  3  4  5  6  7  8  9 10

Os dois vetores parecem iguais, não?

Então, utilizando um operador lógico, vamos verificar o objeto “b” é igual ao objeto “a”.

a==b
##  [1]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE

Alguns valores não são iguais. Como isso é possivel?

a==round(b)
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

Warning2

Não é possível misturar diferentes classes dentro de um mesmo vetor, ao tentar fazer isso repare que o R irá tentar igualar para uma única classe:

errado <- c(TRUE, "vish", 1)
errado
## [1] "TRUE" "vish" "1"

No caso, todos os elementos foram transformados em caracter.

Algumas Dicas:

  • Cuidado com a prioridade das operações, na dúvida, sempre acrescente parenteses conforme seu interesse de prioridade.
  • Lembre-se que, se esquecer de fechar algum ( ou [ ou ", o console do R ficará esperando você fechar indicando um +, nada será processado até que você digite diretamente no console um ) ou aperte ESC.
  • Cuidado para não sobrepor objetos já criados criando outros com o mesmo nome. Use, por exemplo: altura1, altura2.
  • Mantenha no seu script .R somente os comandos que funcionaram e, de preferência, adicione comentários. Você pode, por exemplo, comentar dificuldades encontradas, para que você não cometa os mesmos erros mais tarde.

Se estiver adiantada/o em relação aos colegas, você já pode fazer os exercícios da Sessão 1, se não, faça-os em outro momento e nos envie dúvidas pelo fórum.

Matrizes

As matrizes são outra classe de objetos muito utilizadas no R, com elas podemos realizar operações de maior escala de forma automatizada.

Por serem usadas em operações, normalmente armazenamos nelas elementos numéricos. Para criar uma matriz, determinamos uma sequência de números e indicamos o número de linhas e colunas da matriz:

X <- matrix(1:12, nrow = 6, ncol = 2)
X
##      [,1] [,2]
## [1,]    1    7
## [2,]    2    8
## [3,]    3    9
## [4,]    4   10
## [5,]    5   11
## [6,]    6   12

Podemos também utilizar sequências já armazenadas em vetores para gerar uma matriz, desde que eles sejam numéricos:

W <- matrix(c(x,y), nrow = 6, ncol =2)
W
##      [,1] [,2]
## [1,] 30.1 0.26
## [2,] 30.4 0.30
## [3,] 40.0 0.36
## [4,] 30.2 0.24
## [5,] 30.6 0.27
## [6,] 40.1 0.35

Com elas podemos realizar operações matriciais:

X*2
##      [,1] [,2]
## [1,]    2   14
## [2,]    4   16
## [3,]    6   18
## [4,]    8   20
## [5,]   10   22
## [6,]   12   24
X*X        
##      [,1] [,2]
## [1,]    1   49
## [2,]    4   64
## [3,]    9   81
## [4,]   16  100
## [5,]   25  121
## [6,]   36  144
X%*%t(X)          # Multiplicação matricial
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]   50   58   66   74   82   90
## [2,]   58   68   78   88   98  108
## [3,]   66   78   90  102  114  126
## [4,]   74   88  102  116  130  144
## [5,]   82   98  114  130  146  162
## [6,]   90  108  126  144  162  180

Utilizar essas operações exige conhecimento de álgebra de matrizes, se quiser se aprofundar a respeito, o livro Linear Models in Statistics, Rencher (2008) possui um boa revisão à respeito. Você também pode explorar a sintaxe do R para essas operações neste link.

Acessamos os números internos à matriz dando as coordenadas [linha,coluna], como no exemplo:

W[4,2] # Número posicionado na linha 4 e coluna 2
## [1] 0.24

Retomando…

Paramos aqui no primeiro dia!!

  • Acesse aqui o script .R feito durante o primeiro dia de curso

  • Acesse aqui o script em Rmarkdown do que foi feito no primeiro dia de curso

  • Acesse aqui todos os objetos gerados no primeiro dia de curso. Precisaremos de alguns deles a seguir.

  • Link mencionado: https://rpubs.com/

  • Shortcuts do RStudio

As vezes pode ser informativo dar nomes às colunas e às linhas da matriz, fazemos isso com:

colnames(W) <- c("altura", "diametro")
rownames(W) <- clone
W
##       altura diametro
## GRA02   30.1     0.26
## URO01   30.4     0.30
## URO03   40.0     0.36
## GRA02   30.2     0.24
## GRA01   30.6     0.27
## URO01   40.1     0.35

Essas funções colnames e rownames também funcionam nos data.frames.

Data.frames

Diferente das matrizes, não realizamos operações com os data.frames, mas eles permitem a união de vetores com classes diferentes. Os data frames são semelhantes a tabelas geradas em outros programas, como o excel.

Os data frames são combinações de vetores de mesmo comprimento. Todos os que criamos até agora tem tamanho 6, verifique.

Podemos assim combiná-los em colunas de um único data.frame:

campo1 <- data.frame("clone" = clone,     # Antes do sinal de "="  
                     "altura" = x,        # estabelecemos os nomes  
                     "diametro" = y,      # das colunas
                     "idade" = rep(3:5, 2),
                     "corte"= logico) 
campo1
##   clone altura diametro idade corte
## 1 GRA02   30.1     0.26     3 FALSE
## 2 URO01   30.4     0.30     4 FALSE
## 3 URO03   40.0     0.36     5 FALSE
## 4 GRA02   30.2     0.24     3 FALSE
## 5 GRA01   30.6     0.27     4 FALSE
## 6 URO01   40.1     0.35     5  TRUE

Podemos acessar cada uma das colunas com:

campo1$idade
## [1] 3 4 5 3 4 5

Ou também com:

campo1[,4] 
## [1] 3 4 5 3 4 5

Aqui, o número dentro dos colchetes se refere à coluna, por ser o segundo elemento (separado por vírgula). O primeiro elemento se refere à linha. Como deixamos o primeiro elemento vazio, estaremos nos referindo a todas as linhas para aquela coluna.

Dessa forma, se quisermos obter um conteúdo específico podemos dar as coordenadas com [linha,coluna]:

campo1[1,2] 
## [1] 30.1
  • Obtenha o diâmetro do clone "URO03.
## [1] 0.36

Mesmo se tratando de um data frame, podemos realizar operações com os vetores numéricos que a compõe.

  • Com o diâmetro e a altura das árvores, calcule o volume conforme a fórmula a seguir e armazene em um objeto volume:

\(3.14*(diametro/2)^2*altura\)

## [1] 1.597287 2.147760 4.069440 1.365523 1.751131 3.856116

Agora, vamos adicionar o vetor calculado com o volume ao nosso data.frame. Para isso use a função cbind.

campo1 <- cbind(campo1, volume)
campo1
##   clone altura diametro idade corte   volume
## 1 GRA02   30.1     0.26     3 FALSE 1.597287
## 2 URO01   30.4     0.30     4 FALSE 2.147760
## 3 URO03   40.0     0.36     5 FALSE 4.069440
## 4 GRA02   30.2     0.24     3 FALSE 1.365523
## 5 GRA01   30.6     0.27     4 FALSE 1.751131
## 6 URO01   40.1     0.35     5  TRUE 3.856116
str(campo1)
## 'data.frame':    6 obs. of  6 variables:
##  $ clone   : Factor w/ 4 levels "GRA01","GRA02",..: 2 3 4 2 1 3
##  $ altura  : num  30.1 30.4 40 30.2 30.6 40.1
##  $ diametro: num  0.26 0.3 0.36 0.24 0.27 0.35
##  $ idade   : int  3 4 5 3 4 5
##  $ corte   : logi  FALSE FALSE FALSE FALSE FALSE TRUE
##  $ volume  : num  1.6 2.15 4.07 1.37 1.75 ...

Algumas dicas:

  • Lembre-se que, para construir matrizes e data frames, o número de elementos em cada coluna tem que ser iguais.
  • Caso não saiba o operador ou a função que deve ser utilizada, como o desvio padrão, busque no google algo como “desvio padrão R”, ou melhor “standard deviation R”. Logo nas primeiras páginas você obterá respostas. A comunidade do R é bastante ativa e grande parte das suas perguntas sobre ele já foram respondidas em algum lugar da web.
  • Não esqueça que tudo o que fizer no R precisa ser explicitamente indicado, como uma multiplicação 4ac com 4*a*c. Para gerar um vetor 1,3,2,6 é necessário: c(1,3,2,6).

Listas

Listas consistem em uma coleção de objetos, não necessariamente de mesma classe. Nelas podemos armazenar todos os outros objetos já vistos e recuperá-los pela indexação com [[. Como exemplo, vamos utilizar alguns objetos que já foram gerados.

minha_lista <- list(campo1 = campo1, media_alt = tapply(campo1$altura, campo1$idade, mean), matrix_ex = W)
str(minha_lista)
## List of 3
##  $ campo1   :'data.frame':   6 obs. of  6 variables:
##   ..$ clone   : Factor w/ 4 levels "GRA01","GRA02",..: 2 3 4 2 1 3
##   ..$ altura  : num [1:6] 30.1 30.4 40 30.2 30.6 40.1
##   ..$ diametro: num [1:6] 0.26 0.3 0.36 0.24 0.27 0.35
##   ..$ idade   : int [1:6] 3 4 5 3 4 5
##   ..$ corte   : logi [1:6] FALSE FALSE FALSE FALSE FALSE TRUE
##   ..$ volume  : num [1:6] 1.6 2.15 4.07 1.37 1.75 ...
##  $ media_alt: num [1:3(1d)] 30.1 30.5 40
##   ..- attr(*, "dimnames")=List of 1
##   .. ..$ : chr [1:3] "3" "4" "5"
##  $ matrix_ex: num [1:6, 1:2] 30.1 30.4 40 30.2 30.6 40.1 0.26 0.3 0.36 0.24 ...
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ : chr [1:6] "GRA02" "URO01" "URO03" "GRA02" ...
##   .. ..$ : chr [1:2] "altura" "diametro"

Quero acessar o data.frame campo1

minha_lista[[1]] 
##   clone altura diametro idade corte   volume
## 1 GRA02   30.1     0.26     3 FALSE 1.597287
## 2 URO01   30.4     0.30     4 FALSE 2.147760
## 3 URO03   40.0     0.36     5 FALSE 4.069440
## 4 GRA02   30.2     0.24     3 FALSE 1.365523
## 5 GRA01   30.6     0.27     4 FALSE 1.751131
## 6 URO01   40.1     0.35     5  TRUE 3.856116
# ou
minha_lista$campo1
##   clone altura diametro idade corte   volume
## 1 GRA02   30.1     0.26     3 FALSE 1.597287
## 2 URO01   30.4     0.30     4 FALSE 2.147760
## 3 URO03   40.0     0.36     5 FALSE 4.069440
## 4 GRA02   30.2     0.24     3 FALSE 1.365523
## 5 GRA01   30.6     0.27     4 FALSE 1.751131
## 6 URO01   40.1     0.35     5  TRUE 3.856116

Para acessar uma coluna específica no data.frame campo1, que está dentro da minha_lista:

minha_lista[[1]][[3]]
## [1] 0.26 0.30 0.36 0.24 0.27 0.35
# ou
minha_lista[[1]]$diametro
## [1] 0.26 0.30 0.36 0.24 0.27 0.35
# ou
minha_lista$campo1$diametro
## [1] 0.26 0.30 0.36 0.24 0.27 0.35

Listas são muito úteis, por exemplo, quando vamos utilizar/gerar diversos objetos dentro de um loop.

Arrays

Este é um tipo de objeto que você provavelmente não irá utilizar agora no início, mas é bom saber da sua existência. São utilizados para armazenar dados com mais de duas dimensões. Por exemplo, se criarmos um array:

(meu_array <- array(1:24, dim = c(2,3,4)))
## , , 1
## 
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6
## 
## , , 2
## 
##      [,1] [,2] [,3]
## [1,]    7    9   11
## [2,]    8   10   12
## 
## , , 3
## 
##      [,1] [,2] [,3]
## [1,]   13   15   17
## [2,]   14   16   18
## 
## , , 4
## 
##      [,1] [,2] [,3]
## [1,]   19   21   23
## [2,]   20   22   24

Teremos quatro matrizes com duas linhas e três colunas e os números de 1 a 24 estarão distribuídos nelas por colunas.

Se estiver adiantada/o em relação aos colegas, você já pode fazer os exercícios da Sessão 2, se não, faça-os em outro momento e nos envie dúvidas pelo fórum.

  • Obtenha o arquivo RData com todos os objetos criados até então no tutorial aqui.

Coloque ambos no seu Diretório de Trabalho

Importando e exportando dados

Os arquivos RData são exclusivos do R, clicando duas vezes no arquivo ou utilizando:

load("dia1.RData")

Você vai recuperar todos os objetos gerados até agora no tutorial. Para gerar esse arquivo RData, eu rodei todos os códigos daqui para cima e usei:

save.image(file = "dia1.RData")

Este comando salva tudo o que você tem no seu Ambiente Global (todos os objetos que aparecem ali no canto direito superior). Você pode também salvar somente um objeto com:

save(campo1, file = "campo1.RData")

Se removermos ele do nosso Ambiente Global com:

rm(campo1)  # Certifique-se que salvou o arquivo RData antes de removê-lo

Podemos facilmente obtê-lo novamente com:

load("campo1.RData")

O formato RData é exclusivo para o R, ele é interessante de ser usado para fazer o que estamos fazendo, paramos a análise em um dia, vamos continuar em um outro e não queremos ter que rodar tudo de novo. Mas muitas vezes precisamos exportar nossos dados para outros programas, que exigem outros formatos, como, por exemplo, .txt ou .csv. Para isso utilizamos:

write.table(campo1, file = "campo1.txt", sep = ";", dec = ".", row.names = FALSE)
write.csv(campo1, file = "campo1.csv", row.names = TRUE)

Obs: Você pode adquirir pacotes para exportar e importar dados com outros fomatos, como exemplo o pacote xlsx exporta e importa dados com formato do excel. O pacote vroom pode ser utilizado para compactar grandes tabelas.

Ao exportar, há diversas opções para a formatação do arquivo, é importante considerá-las se o arquivo for usado em outro sofware posteriormente.

Abra os arquivos gerados para visualizar sua formatação.

Esses arquivos podem ser lidos novamente pelo R, utilizando as funções e suas especificações:

campo1_txt <- read.table(file = "campo1.txt", sep=";", dec=".", header = TRUE)
campo1_csv <- read.csv(file = "campo1.csv")
head(campo1_txt)
head(campo1_csv)

Agora que aprendemos a importar dados, vamos trabalhar com o conjunto gerado a partir dos participantes da disciplina Biometria de Marcadores - Turma de 2021.

A planilha com os dados está disponível no link abaixo, adicione-a ao seu diretório de trabalho ou indique o caminho da pasta ao importá-la para dentro do R, como a seguir.

Aqui usaremos o argumento stringAsFactors que impede que o R transforme os vetores da tabela em fatores, os quais são mais difíceis de trabalhar. O argumento na.strings irá indicar como foram nomeados os dados perdidos.

dados <- read.csv(file = "dados_alunos2021.csv", stringsAsFactors = FALSE, na.strings="-", header = T, dec = ",")
head(dados)
load("dados_alunos2021.RData")

Vamos explorar a estrutura dos dados coletados:

str(dados)
## 'data.frame':    116 obs. of  7 variables:
##  $ Categoria.                                                                                                                                                                                                                                            : chr  "Doutorado" "Doutorado" "Mestrado" "Outro" ...
##  $ Qual.seu.curso.de.graduação.                                                                                                                                                                                                                          : chr  "Agronomia" "Agronomia" "Biotecnologia" "Licenciatura em Ciências Biológicas" ...
##  $ Qual.seu.nível.de.conhecimento.sobre.Genética.                                                                                                                                                                                                        : chr  "Avançado" "Avançado" "Intermediário" "Intermediário" ...
##  $ Qual.seu.nível.de.conhecimento.sobre.Estatística.                                                                                                                                                                                                     : chr  "Intermediário" "Intermediário" "Básico" "Intermediário" ...
##  $ Qual.seu.nível.de.conhecimento.sobre..Genética.Estatística..                                                                                                                                                                                          : chr  "Intermediário" "Intermediário" "0" "Intermediário" ...
##  $ Qual.a.latitude.do.local.onde.vai.estar.para.assistir.as.aulas..ATENÇÃO..use.notação.do.tipo..22.709556..com.decimais..e.confira.antes.de.postar..Não.é.usual.alunos.assistirem.as.aulas.no.meio.do.oceano..Use.o.Google.Maps.para.fazer.corretamente.: num  -25.5 -22.7 -15.9 52.1 -22.8 ...
##  $ Qual.a.longitude.do.local.onde.vai.estar.para.assistir.as.aulas..ATENÇÃO..use.notação.do.tipo..47.633866..com.decimais..e.confira.antes.de.postar..Não.é.usual.alunos.assistirem.as.aulas.no.meio.do.oceano..Use.o.Google.Maps.fazer.corretamente.    : num  -54.6 -47.6 -48.1 -106.7 -47.7 ...
# também
dim(dados)
## [1] 116   7

Repare que nos nomes das colunas ainda estão as perguntas completas feitas no formulário, vamos alterar para nomes mais fáceis de trabalhar:

colnames(dados)
## [1] "Categoria."                                                                                                                                                                                                                                            
## [2] "Qual.seu.curso.de.graduação."                                                                                                                                                                                                                          
## [3] "Qual.seu.nível.de.conhecimento.sobre.Genética."                                                                                                                                                                                                        
## [4] "Qual.seu.nível.de.conhecimento.sobre.Estatística."                                                                                                                                                                                                     
## [5] "Qual.seu.nível.de.conhecimento.sobre..Genética.Estatística.."                                                                                                                                                                                          
## [6] "Qual.a.latitude.do.local.onde.vai.estar.para.assistir.as.aulas..ATENÇÃO..use.notação.do.tipo..22.709556..com.decimais..e.confira.antes.de.postar..Não.é.usual.alunos.assistirem.as.aulas.no.meio.do.oceano..Use.o.Google.Maps.para.fazer.corretamente."
## [7] "Qual.a.longitude.do.local.onde.vai.estar.para.assistir.as.aulas..ATENÇÃO..use.notação.do.tipo..47.633866..com.decimais..e.confira.antes.de.postar..Não.é.usual.alunos.assistirem.as.aulas.no.meio.do.oceano..Use.o.Google.Maps.fazer.corretamente."
colnames(dados) = c("Ocupacao", "Graduacao", "Conhecimentos_Genetica", "Conhecimentos_Estatistica", "Conhecimento_Gen_Est", 
                   "Latitude", "Longitude")
colnames(dados)
## [1] "Ocupacao"                  "Graduacao"                
## [3] "Conhecimentos_Genetica"    "Conhecimentos_Estatistica"
## [5] "Conhecimento_Gen_Est"      "Latitude"                 
## [7] "Longitude"
str(dados)
## 'data.frame':    116 obs. of  7 variables:
##  $ Ocupacao                 : chr  "Doutorado" "Doutorado" "Mestrado" "Outro" ...
##  $ Graduacao                : chr  "Agronomia" "Agronomia" "Biotecnologia" "Licenciatura em Ciências Biológicas" ...
##  $ Conhecimentos_Genetica   : chr  "Avançado" "Avançado" "Intermediário" "Intermediário" ...
##  $ Conhecimentos_Estatistica: chr  "Intermediário" "Intermediário" "Básico" "Intermediário" ...
##  $ Conhecimento_Gen_Est     : chr  "Intermediário" "Intermediário" "0" "Intermediário" ...
##  $ Latitude                 : num  -25.5 -22.7 -15.9 52.1 -22.8 ...
##  $ Longitude                : num  -54.6 -47.6 -48.1 -106.7 -47.7 ...

Manipulando os dados

Agora usaremos os dados que temos para aprender diferentes comandos e funções do Ambiente R.

Primeiro, vamos verificar quantos alunos responderam as questões do formulario da disciplina, contando o número de linhas, para isso use a função nrow.

nrow(dados)
## [1] 116

Vamos então verificar se temos no nosso grupo pessoas que compartilham a mesma graduação e ocupação.

Podemos verificar isso facilmente com a função table, que indica a frequência de cada observação:

table(dados$Graduacao)
table(dados$Ocupacao)

Estruturas condicionais

if e else

Para nossa próxima atividade com os dados, vamos primeiro entender como funcionam as estruturas if e else.

Nas funções condicionais if e else, estabelecemos uma condição para if, se ela for verdade a atividade será realizada, caso contrário (else) outra tarefa será. Como no exemplo:

if(2 >3){
  cat("dois é maior que três")
} else {
  cat("dois não é maior que três")
}
## dois não é maior que três
  • Descubra a Nivel de Conhecimentos em Genetica (3ª coluna) da segunda pessoa que o respondeu (linha 2). Envie uma mensagem motivacional se ela possuir conhecimentos basicos, outra se a pessoa ja possuir conhecimento Intermediario ou Avançado (restante das respostas). (dica: o sinal == se refere a “exatamente igual a”)
if(dados[2,3] =="Básico"){
  cat("Força, Mendel acredita em você!")
} else {
  cat("Mendel agradece a preferência")
}
## Mendel agradece a preferência

Podemos espeficiar mais do que uma condição repetindo a estrutura if else: Agora vamos estudar a ocupação das pessoas que responderam ao questionário.

if(dados[2,1] == "Mestrado"){
  cat("Força, o quinto dia útil esta chegando!")
} else if (dados[2,1] == "Doutorado"){
  cat("Assim como seus amigos do mestrado, acredite até sexta a bolsa cai!")
} else {
  cat("Esse já tem a carteira assinada, que beleza!")
}
## Assim como seus amigos do mestrado, acredite até sexta a bolsa cai!

Também podemos fazer uso das funções any e all. Lembrando como any e all funcionam:

x <- 1:10
x
##  [1]  1  2  3  4  5  6  7  8  9 10
all(x > 0)
## [1] TRUE
any(x > 0)
## [1] TRUE
all(x > 9)
## [1] FALSE
any(x > 9)
## [1] TRUE
all(x > 10)
## [1] FALSE
any(x > 10)
## [1] FALSE

Podemos utilizar essas funções para testar se alguém de nós mora no centro de Piracicaba:

range(dados$Latitude)

if(any(dados[,6] ==  -22.725)){
  cat("Alguem mora no centro de Piracicaba")
} else{
  cat("Ninguem mora no centro de Piracicaba.")
}

if(all(dados[,6] ==  -22.725)){
  cat("Todos moram no Centro de Piracicaba.")
} else{
  cat("Nem todos moram no centro de Piracicaba")
}

Usando a mesma lógica: será que algum de nós está no hemisfério norte do globo (latitude 6ª coluna maior que 0)? Se sim, diga para essa pessoa testar o sentido que a água do vaso sanitário gira.

if(any(dados[,6] > 0)){
  cat("Participantes", which(dados[,6] > 0), "vocês podem testar em que sentido a água do vaso sanitário gira aí?")
} 
## Participantes 4 13 23 38 40 49 51 67 72 115 vocês podem testar em que sentido a água do vaso sanitário gira aí?

Switch

Uma outra estrutura que também pode ser usada com o mesmo propósito é o switch. Esta estrutura é mais utilizada quando trabalhado com caracteres. Por isso vamos aplicá-la também para a ocupação para vermos como pode ser mais simples (1ª coluna) o que a segunda e a quarta pessoa fazem.

switch(dados[2,1],
  Mestrado = cat("Força, o quinto dia util esta chegando!"),
  Doutorado = cat("Assim como seus amigos do mestrado, acredite ate sexta a bolsa cai!"),
  cat("Esse ja tem a carteira assinada, que beleza!")
)
## Assim como seus amigos do mestrado, acredite ate sexta a bolsa cai!
switch(dados[4,1],
  Mestrado = cat("Força, o quinto dia util esta chegando!"),
  Doutorado = cat("Assim como seus amigos do mestrado, acredite ate sexta a bolsa cai!"),
  cat("Esse ja tem a carteira assinada, que beleza!")
)
## Esse ja tem a carteira assinada, que beleza!

A estrutura switch costuma ser mais rápida que o if e else. Quando lidamos com grande quantidade de dados isso pode ser uma grande vantagem.

Mas repare que só é possível utilizar essas estruturas para um elemento individual do vetor ou em todo ele, se quisermos percorrer os elementos individualmente precisamos recorrer a outro recurso.

Estruturas de repetição

For

Esse recurso pode ser a função for, uma função muito utilizada e poderosa. Ela constitui uma estrutura de loop, pois irá aplicar a mesma atividade repetidamente até atingir uma determinada condição. Veja exemplos:

for(i in 1:10){
  print(i)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
test <- vector()
for(i in 1:10){
  test[i] <- i+4 
}
test
##  [1]  5  6  7  8  9 10 11 12 13 14

Nos casos acima, i funciona como um índice que irá variar de 1 até 10 a operação determinada entre chaves.

Com essa estrutura, podemos repetir a operação realizada com as estruturas if e else para todo o vetor:

for(i in 1:nrow(dados)){
  if(dados[i,1] == "Mestrado"){
    print("Força, o quinto dia útil esta chegando!")
  } else if (dados[i,1] == "Doutorado"){
    print("Assim como seus amigos do mestrado, acredite até sexta a bolsa cai!")
  } else {
    print("Esse já tem a carteira assinada, que beleza!")
  }
}

Dica: Identação

Repare a diferença:

# Sem identação
for(i in 1:nrow(dados)){
if(dados[i,1] == "Mestrado"){
print("Força, o quinto dia útil esta chegando!")
} else if (dados[i,1] == "Doutorado"){
print("Assim como seus amigos do mestrado, acredite até sexta a bolsa cai!")
} else {
print("Esse já tem a carteira assinada, que beleza!")
}
}

# Com identação correta
for(i in 1:nrow(dados)){
  if(dados[i,1] == "Mestrado"){
    print("Força, o quinto dia útil esta chegando!")
  } else if (dados[i,1] == "Doutorado"){
    print("Assim como seus amigos do mestrado, acredite até sexta a bolsa cai!")
  } else {
    print("Esse já tem a carteira assinada, que beleza!")
  }
}

O editor de código do RStudio tem uma facilitação para identar códigos em R, selecione a área que deseja identar e aperte Ctrl-i.

Agora vamos trabalhar com a coluna 2, que possui a informação da graduação dos participantes. Repare que a função table retorna diferentes categorias que poderiam ser resumidas em apenas uma, como “Engenharia agronômica” e “Agronomia”. Vamos utilizar um loop para descobrir quais responderam áreas relacionadas à “Agro”. Depois, quais dessas respostas não foram “Agronomia” e pedir para que este participante modifique a resposta digitando apenas “Agronomia”.

Dica 1: Para identificar o padrão “Agro” podemos utilizar a função grepl. Dica 2: Podemos utilizar if dentro de if

# Exemplo do uso da função grepl
dados[,2]
##   [1] "Agronomia"                                                
##   [2] "Agronomia"                                                
##   [3] "Biotecnologia"                                            
##   [4] "Licenciatura em Ciências Biológicas"                      
##   [5] "Agronomia"                                                
##   [6] "Agronomia"                                                
##   [7] "Zootecnia"                                                
##   [8] "Agronomia"                                                
##   [9] "Agronomia"                                                
##  [10] "Engenharia Florestal"                                     
##  [11] "Bacharel em Agronomia"                                    
##  [12] "Engenharia Agronômica"                                    
##  [13] "Engenharia Agrícola"                                      
##  [14] "Agronomia"                                                
##  [15] "Engenharia Agronômica"                                    
##  [16] "Ciências Biológicas"                                      
##  [17] "Agronomia"                                                
##  [18] "Engenheiro Florestal"                                     
##  [19] "Genética e Melhoramento de Plantas"                       
##  [20] "Agronomia"                                                
##  [21] "Agronomia"                                                
##  [22] "Engenharia Agronômica"                                    
##  [23] "Agronomia"                                                
##  [24] "Agronomia"                                                
##  [25] "Ciências Biológicas"                                      
##  [26] "Agronomia"                                                
##  [27] "Ciências Biológicas"                                      
##  [28] "Engenharia Agronômica"                                    
##  [29] "Ciências Biológicas"                                      
##  [30] "Agronomia"                                                
##  [31] "Biotecnologia"                                            
##  [32] "Biologia"                                                 
##  [33] "Agronomia"                                                
##  [34] "Biologia"                                                 
##  [35] "Agronomia"                                                
##  [36] "Biologia"                                                 
##  [37] "Agronomia"                                                
##  [38] "Melhoramento genético"                                    
##  [39] "FAEM - UFPEL"                                             
##  [40] "Agronomia"                                                
##  [41] "Ciências Biológicas"                                      
##  [42] "Ciências Biológicas"                                      
##  [43] "Agronomia"                                                
##  [44] "Biologia"                                                 
##  [45] "Agronomia"                                                
##  [46] "Agronomia"                                                
##  [47] "Eng. Agronômica"                                          
##  [48] "Zootecnia"                                                
##  [49] "Agronomia"                                                
##  [50] "Biotecnologia"                                            
##  [51] "Agronomia"                                                
##  [52] "Agronomia"                                                
##  [53] "Agronomia"                                                
##  [54] "Agronomia"                                                
##  [55] "Agronomia"                                                
##  [56] "Agronomia"                                                
##  [57] "Agronomia"                                                
##  [58] "Genética e Melhoramento"                                  
##  [59] "Agronomia"                                                
##  [60] "Agronomia"                                                
##  [61] "Agronomia"                                                
##  [62] "Ciências bilógicas"                                       
##  [63] "Agronomia"                                                
##  [64] "Biologia"                                                 
##  [65] "Genética e Melhoramento de Plantas"                       
##  [66] "Agronomia"                                                
##  [67] "Agronomia"                                                
##  [68] "Agronomia"                                                
##  [69] "Agronomia"                                                
##  [70] "Agronomia"                                                
##  [71] "Agronomia"                                                
##  [72] "Agronomia"                                                
##  [73] "Agronomia"                                                
##  [74] "Engeheria em Biotecnologia Vegetal (Chile)"               
##  [75] "AGRONOMIA"                                                
##  [76] "Engenharia Agronômica"                                    
##  [77] "Agronomia"                                                
##  [78] "Agronomia"                                                
##  [79] "Biología"                                                 
##  [80] "Agronomia"                                                
##  [81] "Ciências Biológicas"                                      
##  [82] "Agronomia"                                                
##  [83] "Agronomia"                                                
##  [84] "Agronomia"                                                
##  [85] "Agronomia"                                                
##  [86] "Agronomia"                                                
##  [87] "Ciências Biológicas"                                      
##  [88] "Agronomia"                                                
##  [89] "Agronomia"                                                
##  [90] "Agronomia"                                                
##  [91] "Agronomia"                                                
##  [92] "Agronomia"                                                
##  [93] "Engenharia Biotecnológica"                                
##  [94] "Agronomia"                                                
##  [95] "Agronomia"                                                
##  [96] "Engenharia Florestal"                                     
##  [97] "Agronomia"                                                
##  [98] "Agronomia"                                                
##  [99] "Biologia"                                                 
## [100] "Biologia"                                                 
## [101] "Ciências Biológicas"                                      
## [102] "Agronomia"                                                
## [103] "Agronomia"                                                
## [104] "Agronomia"                                                
## [105] "Engenheiro Agrônomo"                                      
## [106] "Genética e Melhoramento"                                  
## [107] "Agronomia"                                                
## [108] "Agronomia"                                                
## [109] "Biotecnologia"                                            
## [110] "Agronomia"                                                
## [111] "Agronomia"                                                
## [112] "Biotecnologia"                                            
## [113] "Engenharia Agronômica / Licenciatura em Ciências Agrárias"
## [114] "Ciencias Biologicas"                                      
## [115] "Agronomia"                                                
## [116] "Eng. Florestal"
grepl("Agro", dados[,2]) # Quais linhas contém os caracteres "Agro"
##   [1]  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE
##  [13] FALSE  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
##  [25] FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE
##  [37]  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE  TRUE FALSE
##  [49]  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE
##  [61]  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
##  [73]  TRUE FALSE FALSE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE
##  [85]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE
##  [97]  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE
## [109] FALSE  TRUE  TRUE FALSE  TRUE FALSE  TRUE FALSE
dados[grepl("Agro", dados[,2]),2]
##  [1] "Agronomia"                                                
##  [2] "Agronomia"                                                
##  [3] "Agronomia"                                                
##  [4] "Agronomia"                                                
##  [5] "Agronomia"                                                
##  [6] "Agronomia"                                                
##  [7] "Bacharel em Agronomia"                                    
##  [8] "Engenharia Agronômica"                                    
##  [9] "Agronomia"                                                
## [10] "Engenharia Agronômica"                                    
## [11] "Agronomia"                                                
## [12] "Agronomia"                                                
## [13] "Agronomia"                                                
## [14] "Engenharia Agronômica"                                    
## [15] "Agronomia"                                                
## [16] "Agronomia"                                                
## [17] "Agronomia"                                                
## [18] "Engenharia Agronômica"                                    
## [19] "Agronomia"                                                
## [20] "Agronomia"                                                
## [21] "Agronomia"                                                
## [22] "Agronomia"                                                
## [23] "Agronomia"                                                
## [24] "Agronomia"                                                
## [25] "Agronomia"                                                
## [26] "Agronomia"                                                
## [27] "Eng. Agronômica"                                          
## [28] "Agronomia"                                                
## [29] "Agronomia"                                                
## [30] "Agronomia"                                                
## [31] "Agronomia"                                                
## [32] "Agronomia"                                                
## [33] "Agronomia"                                                
## [34] "Agronomia"                                                
## [35] "Agronomia"                                                
## [36] "Agronomia"                                                
## [37] "Agronomia"                                                
## [38] "Agronomia"                                                
## [39] "Agronomia"                                                
## [40] "Agronomia"                                                
## [41] "Agronomia"                                                
## [42] "Agronomia"                                                
## [43] "Agronomia"                                                
## [44] "Agronomia"                                                
## [45] "Agronomia"                                                
## [46] "Agronomia"                                                
## [47] "Agronomia"                                                
## [48] "Engenharia Agronômica"                                    
## [49] "Agronomia"                                                
## [50] "Agronomia"                                                
## [51] "Agronomia"                                                
## [52] "Agronomia"                                                
## [53] "Agronomia"                                                
## [54] "Agronomia"                                                
## [55] "Agronomia"                                                
## [56] "Agronomia"                                                
## [57] "Agronomia"                                                
## [58] "Agronomia"                                                
## [59] "Agronomia"                                                
## [60] "Agronomia"                                                
## [61] "Agronomia"                                                
## [62] "Agronomia"                                                
## [63] "Agronomia"                                                
## [64] "Agronomia"                                                
## [65] "Agronomia"                                                
## [66] "Agronomia"                                                
## [67] "Agronomia"                                                
## [68] "Agronomia"                                                
## [69] "Agronomia"                                                
## [70] "Agronomia"                                                
## [71] "Agronomia"                                                
## [72] "Agronomia"                                                
## [73] "Engenharia Agronômica / Licenciatura em Ciências Agrárias"
## [74] "Agronomia"
for(i in 1:nrow(dados)){
  if(grepl("Agro", dados[i,2])){
    if(dados[i,2] != "Agronomia"){
     print("Por favor, substitua sua resposta por Agronomia.") 
    }
  } 
}
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."

Para que seja possível imprimir conteúdo de objetos durante o loop, usamos a função cat, ela não separa cada resposta em uma linha, precisamos colocar o \n indicando a quebra de linha.

Agora vamos nos mesmos homogeneizar essas informações. Podemos armazenar em uma variável a posição das linhas identificadas, então corrigiremos manualmente somente essas:

homog <- vector()
for(i in 1:nrow(dados)){
  if(grepl("Agro", dados[i,2])){
    if(dados[i,2] != "Agronomia"){
     print("Por favor, substitua sua resposta por Agronomia.") 
     homog <- c(homog, i)
    }
  } 
}
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
## [1] "Por favor, substitua sua resposta por Agronomia."
homog
## [1]  11  12  15  22  28  47  76 113

Como você faria para corrigir esses elementos errados? Tente!

‘dados[homog, 2] <- “Agronomia”’

While

Nesse tipo de estrutura de repetição a tarefa será realizada até que seja atingida determinada condição.

x <- 1

while(x < 5){
  x <- x + 1
  cat(x)
}
## 2345

É muito importante que nessa estrutura a condição seja atingida, caso contrário o loop irá funcionar infinitamente e você terá que interrompê-lo por meios externos, como, se este utilizando RStudio, clicar no simbolo em vermelho no canto direito superior da janela do console, ou apertar Ctrl+C no console.

Não é muito difícil disso acontecer, basta um pequeno erro como:

x <- 1

while(x < 5){
  x + 1
  cat(x)
}

Aqui podemos utilizar os comandos break e next para atender a outras condições, como:

x <- 1

while(x < 5){
  x <- x + 1
  if(x==4) break
  cat(x)
}
## 23
x <- 1

while(x < 5){
  x <- x + 1
  if(x==4) next
  cat(x)
}
## 235

Repeat

Esta estrutura também exige uma condição de parada, mas esta condição é necessariamente colocada dentro do bloco de código com o uso do break. Ela então repete o bloco de código até a condição o interrompa.

x <- 1
repeat{
  x <- x+1
  cat(x)
  if(x==4) break
}
## 234

Loops dentro de loops

É possível também utilizarmos estruturas de repetição dentro de estruturas de repetição. Por exemplo, se quisermos trabalhar tanto nas colunas como nas linhas de uma matrix.

# Criando uma matrix vazia
ex_mat <- matrix(nrow=10, ncol=10)

# cada número dentro da matrix será o produto no índice da coluna pelo índice da linha
for(i in 1:dim(ex_mat)[1]) {
  for(j in 1:dim(ex_mat)[2]) {
    ex_mat[i,j] = i*j
  }
}

Outro exemplo de uso:

var1 <- c("fertilizante1", "fertilizante2")
var2 <- c("ESS", "URO", "GRA")

w <- 1
for(i in var1){
  for(j in var2){
    nome_arquivo <- paste0(i,"_planta_",j,".txt")
    arquivo <- data.frame("bloco" = "fake_data", "tratamento" ="fake_data")
    write.table(arquivo, file = nome_arquivo)
    w <- w + 1
  }
}

# Verifique seu diretorio de trabalho, arquivos devem ter sido gerados

Fizemos um vídeo com mais detalhes sobre loops no R (quando cursamos a disciplina de Biometria de Marcadores), aumentem nossa quantidade de views e likes por .

Se estiver adiantada/o em relação aos colegas, você já pode fazer os exercícios da Sessão 3, se não, faça-os em outro momento e nos envie dúvidas pelo fórum.

Algumas dicas:

  • Cuidado ao rodar o mesmo comando mais de uma vez, algumas variáveis podem não ser mais como eram antes. Para que o comando funcione da mesma forma é necessário que os objetos de entrada estejam da forma como você espera.
  • Lembrem-se que = é para definir objetos e == é o sinal de igualdade.
  • Nas estruturas condicionais e de repetição, lembrem-se que é necessário manter a sintaxe esperada: If(){} e for(i in 1:10){}. No for, podemos trocar a letra que será o índice, mas é sempre necessário fornecer uma sequência de inteiros ou caracteres.
  • Usar identação ajuda a visualizar o começo e fim de cada estrutura de código e facilita o abrir e fechar de chaves. Identação são aqueles espaços que usamos antes da linha, como:
# Criando uma matrix vazia
ex_mat <- matrix(nrow=10, ncol=10)

# cada número dentro da matrix será o produto no índice da coluna pelo índice da linha
for(i in 1:dim(ex_mat)[1]) {   # Primeiro nível, não tem espaço
  for(j in 1:dim(ex_mat)[2]) { # Segundo nível tem um espaço (tab)
    ex_mat[i,j] = i*j          # Terceiro nível tem dois espaços
  }                            # Fechei o segundo nível
}                              # Fechei o primeiro nível

Elaboração de funções

Normalmente é uma boa prática criar um bloco de código se vai realizar aquela ação poucas vezes. Se for realizar várias vezes a ação e de uma vez só, vale a pena fazer um loop. Mas, se for realizar diversas vezes e o objeto de entrada for modificado, vale a pena fazer uma função. E, na hierarquia, quando tiver acumulado muitas funções para realizar uma tarefa mais complexa, vale a pena construir um pacote.

A função também é considerada um objeto no R, portanto você a atribui à uma variável. Procure nomear a função com um nome curto e intuitivo em relação à tarefa que ela executa. Essa nem sempre é uma tarefa fácil.

[referência](https://www.reddit.com/r/ProgrammerHumor/comments/5z6n8p/every_time/)

Para criar uma função obedeça a seguinte estrutura:

nome_da_funcao <- function(argumento1, argumento2,...){
  corpo da função
}

Como exemplo, vamos criar a função quadra. Estabelecemos os argumentos da função, nesse caso x. Entre as chaves fica todo o corpo da função. Se você quer que a função retorne algum valor, é necessário utilizar o return.

quadra <- function(x){
  z <- x*x
  return(z)
}

quadra(3)
## [1] 9
quadra(4)
## [1] 16
qualquer_nome <- 4
quadra(qualquer_nome)
## [1] 16

O ambiente de variáveis utilizado pela função é diferente do ambiente global em que são armazenadas todos as variáveis já criadas. Variáveis criadas no corpo da função não pertencerão ao ambiente global, mas as contidas no ambiente global podem ser acessadas pela função. Observe:

rm(z) # certificando que não há uma variável/objeto z criada/o

# Na função quadra, criamos uma variável z internamente
quadra(qualquer_nome)
z # mais ele não é criado no ambiente global, só no ambiente interno da função, e z desaparece assim que a função termina sua tarefa

Agora vamos criar uma outra funçao que usa y, mas não possui y como argumento. Atenção: não façam isso na rotina de vocês, sempre estabeleçam tudo o que for ser usado no corpo da função nos argumentos dela, estamos fazendo aqui apenas para fins didádicos.

rm(y)
quadra_mais_y <- function(x){
  z <- x*x + y
  return(z)
}

quadra_mais_y(4) # não temos ainda y

y <- 2

quadra_mais_y(4) # quando temos, a função acessa o y do ambiente global

Agora, vamos criar uma função para indicar quais participantes estão no hemisfério sul/norte e à oriente/ocidente do meridiano de Greenwich. Lembrando que latitudes > 0 se referem ao hemisfério norte e longitudes > 0 ao hemisfério oriental.

localizacao <- function(latitude, longitude){
  hemisferio <- vector()
  hemisferio[which(latitude > 0)] <- "Norte"
  hemisferio[which(latitude < 0)] <- "Sul"
  hemisferio[which(latitude == 0)] <- "Equador"
  
  meridiano <- vector()
  meridiano[which(longitude > 0)] <- "Oriente"
  meridiano[which(longitude < 0)] <- "Ocidente"
  meridiano[which(longitude == 0)] <- "Meridiano de Greenwich"
  
  df <- data.frame(hemisferio, meridiano)
  return(df)
}

localizacao(latitude = dados[,6], longitude = dados[,7])
##     hemisferio meridiano
## 1          Sul  Ocidente
## 2          Sul  Ocidente
## 3          Sul  Ocidente
## 4        Norte  Ocidente
## 5          Sul  Ocidente
## 6          Sul  Ocidente
## 7          Sul  Ocidente
## 8          Sul  Ocidente
## 9          Sul  Ocidente
## 10         Sul  Ocidente
## 11         Sul  Ocidente
## 12         Sul  Ocidente
## 13       Norte  Ocidente
## 14         Sul  Ocidente
## 15         Sul  Ocidente
## 16         Sul  Ocidente
## 17         Sul  Ocidente
## 18         Sul  Ocidente
## 19         Sul  Ocidente
## 20         Sul  Ocidente
## 21         Sul  Ocidente
## 22         Sul  Ocidente
## 23       Norte  Ocidente
## 24         Sul  Ocidente
## 25         Sul  Ocidente
## 26         Sul  Ocidente
## 27         Sul  Ocidente
## 28         Sul  Ocidente
## 29         Sul  Ocidente
## 30         Sul  Ocidente
## 31         Sul  Ocidente
## 32         Sul  Ocidente
## 33         Sul  Ocidente
## 34         Sul  Ocidente
## 35         Sul  Ocidente
## 36         Sul  Ocidente
## 37         Sul  Ocidente
## 38       Norte   Oriente
## 39         Sul  Ocidente
## 40       Norte  Ocidente
## 41         Sul  Ocidente
## 42         Sul  Ocidente
## 43         Sul  Ocidente
## 44         Sul  Ocidente
## 45         Sul  Ocidente
## 46         Sul  Ocidente
## 47         Sul  Ocidente
## 48         Sul  Ocidente
## 49       Norte  Ocidente
## 50         Sul  Ocidente
## 51       Norte  Ocidente
## 52         Sul  Ocidente
## 53         Sul  Ocidente
## 54         Sul  Ocidente
## 55         Sul  Ocidente
## 56         Sul  Ocidente
## 57         Sul  Ocidente
## 58         Sul  Ocidente
## 59         Sul  Ocidente
## 60         Sul  Ocidente
## 61         Sul  Ocidente
## 62         Sul  Ocidente
## 63         Sul  Ocidente
## 64         Sul  Ocidente
## 65         Sul  Ocidente
## 66         Sul  Ocidente
## 67       Norte  Ocidente
## 68         Sul  Ocidente
## 69         Sul  Ocidente
## 70         Sul  Ocidente
## 71         Sul  Ocidente
## 72       Norte  Ocidente
## 73         Sul  Ocidente
## 74         Sul  Ocidente
## 75         Sul  Ocidente
## 76         Sul  Ocidente
## 77         Sul  Ocidente
## 78         Sul  Ocidente
## 79         Sul  Ocidente
## 80         Sul  Ocidente
## 81         Sul  Ocidente
## 82         Sul  Ocidente
## 83         Sul  Ocidente
## 84         Sul  Ocidente
## 85         Sul  Ocidente
## 86         Sul  Ocidente
## 87         Sul  Ocidente
## 88         Sul  Ocidente
## 89         Sul  Ocidente
## 90         Sul  Ocidente
## 91         Sul  Ocidente
## 92         Sul  Ocidente
## 93         Sul  Ocidente
## 94         Sul  Ocidente
## 95         Sul  Ocidente
## 96         Sul  Ocidente
## 97         Sul  Ocidente
## 98         Sul  Ocidente
## 99         Sul  Ocidente
## 100        Sul  Ocidente
## 101        Sul  Ocidente
## 102        Sul  Ocidente
## 103        Sul  Ocidente
## 104        Sul  Ocidente
## 105        Sul  Ocidente
## 106        Sul  Ocidente
## 107        Sul  Ocidente
## 108        Sul  Ocidente
## 109        Sul  Ocidente
## 110        Sul  Ocidente
## 111        Sul  Ocidente
## 112        Sul  Ocidente
## 113        Sul  Ocidente
## 114        Sul  Ocidente
## 115      Norte  Ocidente
## 116        Sul  Ocidente

Agora, aprimore a função acima adicionando também uma coluna que indique a média de conhecimento do participante sobre as três áreas perguntadas. Considere para isso: Básico = 1, Intermediário = 2, Avançado = 3, Sabe o teste F? Fui eu que desenvolvi, mas não publiquei porque sou modesto = 99 e 0 = 0.

# Dica
dados[dados == "Avançado"] <- 3
dados[dados == "Intermediário"] <- 2
dados[dados == "Básico"] <- 1
dados[dados == "Sabe o teste F? Fui eu que desenvolvi, mas não publiquei porque sou modesto"] <- 99
localizacao <- function(latitude, 
                        longitude, 
                        genetica, 
                        estatistica, 
                        genetica_estatistica){
  hemisferio <- vector()
  hemisferio[which(latitude > 0)] <- "Norte"
  hemisferio[which(latitude < 0)] <- "Sul"
  hemisferio[which(latitude == 0)] <- "Equador"
  
  meridiano <- vector()
  meridiano[which(longitude > 0)] <- "Oriente"
  meridiano[which(longitude < 0)] <- "Ocidente"
  meridiano[which(longitude == 0)] <- "Meridiano de Greenwich"
  
  medias <- (as.numeric(genetica) + 
             as.numeric(estatistica) + 
             as.numeric(genetica_estatistica))/3
  
  df <- data.frame(hemisferio, meridiano, round(medias,2))
  return(df)
}

localizacao(dados[,6], dados[,7], genetica = dados[,3], 
            estatistica = dados[,4], genetica_estatistica = dados[,5])
##     hemisferio meridiano round.medias..2.
## 1          Sul  Ocidente             2.33
## 2          Sul  Ocidente             2.33
## 3          Sul  Ocidente             1.00
## 4        Norte  Ocidente             2.00
## 5          Sul  Ocidente             1.00
## 6          Sul  Ocidente             1.67
## 7          Sul  Ocidente             2.00
## 8          Sul  Ocidente             2.00
## 9          Sul  Ocidente             2.33
## 10         Sul  Ocidente            34.33
## 11         Sul  Ocidente             1.33
## 12         Sul  Ocidente             1.00
## 13       Norte  Ocidente             2.33
## 14         Sul  Ocidente             1.67
## 15         Sul  Ocidente             1.67
## 16         Sul  Ocidente             1.33
## 17         Sul  Ocidente             2.00
## 18         Sul  Ocidente             0.67
## 19         Sul  Ocidente             2.00
## 20         Sul  Ocidente             2.67
## 21         Sul  Ocidente             1.67
## 22         Sul  Ocidente             2.00
## 23       Norte  Ocidente             1.00
## 24         Sul  Ocidente             2.67
## 25         Sul  Ocidente             1.00
## 26         Sul  Ocidente             1.00
## 27         Sul  Ocidente             1.67
## 28         Sul  Ocidente             1.67
## 29         Sul  Ocidente             1.33
## 30         Sul  Ocidente             2.67
## 31         Sul  Ocidente             1.67
## 32         Sul  Ocidente             2.00
## 33         Sul  Ocidente             2.00
## 34         Sul  Ocidente             1.67
## 35         Sul  Ocidente             1.67
## 36         Sul  Ocidente             1.33
## 37         Sul  Ocidente             2.67
## 38       Norte   Oriente             1.67
## 39         Sul  Ocidente             2.00
## 40       Norte  Ocidente             2.00
## 41         Sul  Ocidente             2.33
## 42         Sul  Ocidente             1.00
## 43         Sul  Ocidente             1.67
## 44         Sul  Ocidente             2.33
## 45         Sul  Ocidente             2.33
## 46         Sul  Ocidente             0.33
## 47         Sul  Ocidente             2.33
## 48         Sul  Ocidente             1.67
## 49       Norte  Ocidente             2.00
## 50         Sul  Ocidente             1.33
## 51       Norte  Ocidente             2.67
## 52         Sul  Ocidente             2.00
## 53         Sul  Ocidente             2.00
## 54         Sul  Ocidente             2.33
## 55         Sul  Ocidente             2.00
## 56         Sul  Ocidente             1.67
## 57         Sul  Ocidente             1.33
## 58         Sul  Ocidente             1.33
## 59         Sul  Ocidente             1.33
## 60         Sul  Ocidente             2.00
## 61         Sul  Ocidente             1.33
## 62         Sul  Ocidente             2.33
## 63         Sul  Ocidente             2.00
## 64         Sul  Ocidente             2.00
## 65         Sul  Ocidente             2.33
## 66         Sul  Ocidente             2.00
## 67       Norte  Ocidente             2.00
## 68         Sul  Ocidente             2.00
## 69         Sul  Ocidente             1.67
## 70         Sul  Ocidente             2.33
## 71         Sul  Ocidente             2.00
## 72       Norte  Ocidente             2.33
## 73         Sul  Ocidente             1.67
## 74         Sul  Ocidente             2.67
## 75         Sul  Ocidente             2.00
## 76         Sul  Ocidente             1.67
## 77         Sul  Ocidente             2.67
## 78         Sul  Ocidente             1.67
## 79         Sul  Ocidente             1.33
## 80         Sul  Ocidente             2.00
## 81         Sul  Ocidente             2.33
## 82         Sul  Ocidente             2.33
## 83         Sul  Ocidente             1.67
## 84         Sul  Ocidente             2.33
## 85         Sul  Ocidente             2.67
## 86         Sul  Ocidente             2.33
## 87         Sul  Ocidente             1.67
## 88         Sul  Ocidente             1.33
## 89         Sul  Ocidente             1.67
## 90         Sul  Ocidente             2.00
## 91         Sul  Ocidente             2.33
## 92         Sul  Ocidente             1.67
## 93         Sul  Ocidente             1.33
## 94         Sul  Ocidente             1.00
## 95         Sul  Ocidente             2.33
## 96         Sul  Ocidente             2.00
## 97         Sul  Ocidente             1.33
## 98         Sul  Ocidente             2.00
## 99         Sul  Ocidente             3.00
## 100        Sul  Ocidente             2.00
## 101        Sul  Ocidente             2.00
## 102        Sul  Ocidente             1.33
## 103        Sul  Ocidente             2.00
## 104        Sul  Ocidente             1.33
## 105        Sul  Ocidente             2.00
## 106        Sul  Ocidente             3.00
## 107        Sul  Ocidente             2.67
## 108        Sul  Ocidente             2.00
## 109        Sul  Ocidente             3.00
## 110        Sul  Ocidente             2.33
## 111        Sul  Ocidente             2.67
## 112        Sul  Ocidente             3.00
## 113        Sul  Ocidente             1.67
## 114        Sul  Ocidente             2.00
## 115      Norte  Ocidente             3.00
## 116        Sul  Ocidente             2.00

Se é uma função para uso próprio, você saberá como deve ser o objeto de entrada, mas se ela for utilizada por outras pessoas, será necessário, além de uma prévia explicação de suas ações, verificar se o objeto de entrada esta de acordo com o esperado pela função. No nosso exemplo, não faria sentido o usário entrar com números fora do intervalo [-180, 180]. Faça com que a função retorne um erro caso isso aconteça.

localizacao <- function(latitude, 
                        longitude, 
                        genetica, 
                        estatistica, 
                        genetica_estatistica){
  
  if(any(latitude < -180 | latitude > 180)) stop("Valores de latitude inválidos")
  if(any(longitude < -180 | longitude > 180)) stop("Valores de longitude inválidos")
  
  hemisferio <- vector()
  hemisferio[which(latitude > 0)] <- "Norte"
  hemisferio[which(latitude < 0)] <- "Sul"
  hemisferio[which(latitude == 0)] <- "Equador"
  
  meridiano <- vector()
  meridiano[which(longitude > 0)] <- "Oriente"
  meridiano[which(longitude < 0)] <- "Ocidente"
  meridiano[which(longitude == 0)] <- "Meridiano de Greenwich"
  
  medias <- (as.numeric(genetica) + 
             as.numeric(estatistica) + 
             as.numeric(genetica_estatistica))/3
  
  df <- data.frame(hemisferio, meridiano, round(medias,2))
  return(df)
}

localizacao(dados[,6], dados[,7], genetica = dados[,3], 
            estatistica = dados[,4], genetica_estatistica = dados[,5])
##     hemisferio meridiano round.medias..2.
## 1          Sul  Ocidente             2.33
## 2          Sul  Ocidente             2.33
## 3          Sul  Ocidente             1.00
## 4        Norte  Ocidente             2.00
## 5          Sul  Ocidente             1.00
## 6          Sul  Ocidente             1.67
## 7          Sul  Ocidente             2.00
## 8          Sul  Ocidente             2.00
## 9          Sul  Ocidente             2.33
## 10         Sul  Ocidente            34.33
## 11         Sul  Ocidente             1.33
## 12         Sul  Ocidente             1.00
## 13       Norte  Ocidente             2.33
## 14         Sul  Ocidente             1.67
## 15         Sul  Ocidente             1.67
## 16         Sul  Ocidente             1.33
## 17         Sul  Ocidente             2.00
## 18         Sul  Ocidente             0.67
## 19         Sul  Ocidente             2.00
## 20         Sul  Ocidente             2.67
## 21         Sul  Ocidente             1.67
## 22         Sul  Ocidente             2.00
## 23       Norte  Ocidente             1.00
## 24         Sul  Ocidente             2.67
## 25         Sul  Ocidente             1.00
## 26         Sul  Ocidente             1.00
## 27         Sul  Ocidente             1.67
## 28         Sul  Ocidente             1.67
## 29         Sul  Ocidente             1.33
## 30         Sul  Ocidente             2.67
## 31         Sul  Ocidente             1.67
## 32         Sul  Ocidente             2.00
## 33         Sul  Ocidente             2.00
## 34         Sul  Ocidente             1.67
## 35         Sul  Ocidente             1.67
## 36         Sul  Ocidente             1.33
## 37         Sul  Ocidente             2.67
## 38       Norte   Oriente             1.67
## 39         Sul  Ocidente             2.00
## 40       Norte  Ocidente             2.00
## 41         Sul  Ocidente             2.33
## 42         Sul  Ocidente             1.00
## 43         Sul  Ocidente             1.67
## 44         Sul  Ocidente             2.33
## 45         Sul  Ocidente             2.33
## 46         Sul  Ocidente             0.33
## 47         Sul  Ocidente             2.33
## 48         Sul  Ocidente             1.67
## 49       Norte  Ocidente             2.00
## 50         Sul  Ocidente             1.33
## 51       Norte  Ocidente             2.67
## 52         Sul  Ocidente             2.00
## 53         Sul  Ocidente             2.00
## 54         Sul  Ocidente             2.33
## 55         Sul  Ocidente             2.00
## 56         Sul  Ocidente             1.67
## 57         Sul  Ocidente             1.33
## 58         Sul  Ocidente             1.33
## 59         Sul  Ocidente             1.33
## 60         Sul  Ocidente             2.00
## 61         Sul  Ocidente             1.33
## 62         Sul  Ocidente             2.33
## 63         Sul  Ocidente             2.00
## 64         Sul  Ocidente             2.00
## 65         Sul  Ocidente             2.33
## 66         Sul  Ocidente             2.00
## 67       Norte  Ocidente             2.00
## 68         Sul  Ocidente             2.00
## 69         Sul  Ocidente             1.67
## 70         Sul  Ocidente             2.33
## 71         Sul  Ocidente             2.00
## 72       Norte  Ocidente             2.33
## 73         Sul  Ocidente             1.67
## 74         Sul  Ocidente             2.67
## 75         Sul  Ocidente             2.00
## 76         Sul  Ocidente             1.67
## 77         Sul  Ocidente             2.67
## 78         Sul  Ocidente             1.67
## 79         Sul  Ocidente             1.33
## 80         Sul  Ocidente             2.00
## 81         Sul  Ocidente             2.33
## 82         Sul  Ocidente             2.33
## 83         Sul  Ocidente             1.67
## 84         Sul  Ocidente             2.33
## 85         Sul  Ocidente             2.67
## 86         Sul  Ocidente             2.33
## 87         Sul  Ocidente             1.67
## 88         Sul  Ocidente             1.33
## 89         Sul  Ocidente             1.67
## 90         Sul  Ocidente             2.00
## 91         Sul  Ocidente             2.33
## 92         Sul  Ocidente             1.67
## 93         Sul  Ocidente             1.33
## 94         Sul  Ocidente             1.00
## 95         Sul  Ocidente             2.33
## 96         Sul  Ocidente             2.00
## 97         Sul  Ocidente             1.33
## 98         Sul  Ocidente             2.00
## 99         Sul  Ocidente             3.00
## 100        Sul  Ocidente             2.00
## 101        Sul  Ocidente             2.00
## 102        Sul  Ocidente             1.33
## 103        Sul  Ocidente             2.00
## 104        Sul  Ocidente             1.33
## 105        Sul  Ocidente             2.00
## 106        Sul  Ocidente             3.00
## 107        Sul  Ocidente             2.67
## 108        Sul  Ocidente             2.00
## 109        Sul  Ocidente             3.00
## 110        Sul  Ocidente             2.33
## 111        Sul  Ocidente             2.67
## 112        Sul  Ocidente             3.00
## 113        Sul  Ocidente             1.67
## 114        Sul  Ocidente             2.00
## 115      Norte  Ocidente             3.00
## 116        Sul  Ocidente             2.00

Para saber mais sobre desenvolvimento de funções acesse aqui e, um pouco mais avançado, aqui.

Rodando outros scripts .R

As vezes, parte do seu código demanda que você chame algo que foi rodado em outro script. Muitas pessoas também tem o costume de salvar as funções próprias em um script separado. Vamos fazer isso?

  • Abra um novo script .R, copie suas funções para ele e o salve como funcoes.R

Agora, você pode acessa-las usando:

source("funcoes.R")

Se estiver adiantada/o em relação aos colegas, você já pode fazer os exercícios da Sessão 4, se não, faça-os em outro momento e nos envie dúvidas pelo fórum.

Elaboração de gráficos simples

Para outros dados coletados, vamos gerar alguns gráficos simples utilizando as funções básicas do R. Existem pacotes como o ggplot2, plotly e shiny que possuem ferramentas muito poderosas para construção de gráficos, mas exigem um pouco mais de tempo para aprendizagem de sua sintaxe.

Os tipos mais comuns já possuem funções próprias, mas outros gráficos podem ser customizados de acordo com a necessidade do usuário. Vamos iniciar com um simples gráfico de frequências (ou histograma) para os dados de latitude.

hist(dados$Latitude)

Vamos adicionar alguns argumentos para dar uma personalizada:

  • breaks para definir os intervalos para cada barra;

Agora tente fazer o histograma para a Longitude, aproveite para tentar alterar alguns parâmetros. Em seguida, serão apresentados outros gráficos que poderão ser utilizados.

Salvar gráficos

Os gráficos podem ser salvos através dos menus disponíveis no RStudio, ou através de funções que permitem salvar em formatos específicos. Algumas delas são: pdf(); png(); jpeg(); bitmap(). De maneira geral, o parâmetro primordial é fornecer o nome do arquivo que será gerado (contendo sua extensão). Após abrir a função gráfica, deve-se gerar o gráfico de interesse. Por fim, utiliza-se o comando dev.off() para que saída gráfica volte para o console.

png(filename = "hist_rbase.png")
hist(dados$Latitude)
dev.off()

png(filename = "hist_rbase.png", width = 1500, height = 1500, res= 300)
hist(dados$Latitude)
dev.off()

Agora, gere um gráfico e salve-o no formato de seu interesse. Em seguida, crie diversos gráficos dentro de uma mesma função gráfica e estude a saída.

Aplicações de pacotes

Existem diversos pacotes disponíveis para variadas aplicações. Utilizaremos o ggplot2, que está disponível no repositório oficial do R, o CRAN. Portanto para instalá-lo:

install.packages("ggplot2")

Depois disso é necessário recrutá-lo toda vez que iniciar um sessão no R:

library("ggplot2")

O ggplot2 é um pacote que permite a construção de gráficos estatísticos, suas funcionalidades vão muito além do que está disponível nos gráficos básicos do R.

Pratique gerando relatórios no RStudio

Utilize o R no seu dia-a-dia para ir praticando a linguagem. Além das recomendações contidas na primeira apresentação, recomendamos também dar uma olhada em como gerar documentos em pdf e html usando a Markdown. Utilizamos essa metodologia para gerar este tutorial e outras apresentações do curso. Pode ser muito prático no dia-a-dia!

Para utilizar, será necessário a instalação de outros pacotes. Um deles é o próprio rmarkdown:

install.packages("rmarkdown")
library(rmarkdown)

Agora crie um arquivo .Rmd utilizando as facilidades do RStudio, clique no ícone com símbolo + no canto superior esquerdo. Escolha o opção R Markdown. Dê um título ao seu arquivo e escolha a opção html. Ao fazer isso, o RStudio já coloca um template inicial, ja com um cabeçalho:

---
title: "Teste"
author: "Eu"
date: "June 5, 2018"
output: html_document
---

Este é o mais simples possível, você pode otimizá-lo de diversas maneiras. Saiba mais aqui.

O template inicial também traz alguns exemplos de sintaxe do markdown. Observe que utilizando # para títulos de sessões, ## para um nível inferior (subtitulos) e assim por diante. Palavras em negrito são escritas em meia a dois * e existem diversas outras especificações para essa sintaxe. Veja mais sobre ela aqui.

Para compilar o código, basta clicar em Knit. Ele irá pedir para que o arquivo .Rmd seja salvo com algum nome em algum lugar.

O markdown também é capaz de entender diretamente a linguagem html, também a css e latex. Para essa última, o latex precisa estar instalado e todas suas dependências.

Existem alguns pacotes que fornecem templates mais robustos para produção de htmls. Para esse tutorial utilizando o pacote rmdformats e personalizamos suas cores. Experimente:

install.packages("rmdformats")

Agora faça o mesmo procedimento, clique no +, escolha R Markdown e, antes de escolher um título, mude para From Template, escolha o HTML readthedown template. Copie e cole o seguinte texto e aperte Knit.

# Teste1

Isso aqui é um teste só para dar uma olhada no template

## Testinho

Subsessão

* Item

**negrito**

*itálico*

fiz um [link](https://GENt-esalq.github.io/)!

Saiba mais no tutorial do R-bloggers, que acreditamos ser um bom começo! Acesse aqui.

Extra

Algumas ferramentas básicas de análise de dados

Claramente a análise de dados é algo muito específico de cada conjunto de dados e interesses, aqui apenas exemplificaremos o uso de algumas funções do R em duas situações específicas.

Avaliando o clima de Londrina

Vamos utilizar outro conjunto de dados para realizarmos mais avaliações utilizando a função lm. Acesse o conjunto clima_lond:

load("clima_lond.RData")

Para obter os dados de precipitação da cidade de Londrina no primeiro semestre de 2017. Vamos utilizar as funções tapply e lm para avaliar os dados.

Algumas avaliações descritivas podem ser feitas pelo uso do tapply e de gráficos. A função summary também fornece informações gerais do conjunto. É possível usá-la em conjunto com o tapply.

# Verificando se as variáveis categórias estão como fatores
str(clima_lond)
## 'data.frame':    181 obs. of  4 variables:
##  $ dia    : Factor w/ 31 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10 ...
##  $ Mes    : Factor w/ 6 levels "Abril","Fevereiro",..: 3 3 3 3 3 3 3 3 3 3 ...
##  $ prec.mm: Factor w/ 56 levels "0","0.2","0.3",..: 55 52 26 5 21 1 4 1 1 4 ...
##  $ Data   : Factor w/ 181 levels "2017-01-01","2017-01-02",..: 1 2 3 4 5 6 7 8 9 10 ...
clima_lond$dia <- as.factor(clima_lond$dia)

# A precipitação nesse caso é uma variável contínua, nao categórica, para transformá-la use:

clima_lond$prec.mm <- as.numeric(as.character(clima_lond$prec.mm))

# Já com o tapply podemos ver as diferenças

tapply(clima_lond$prec.mm, clima_lond$Mes, summary)
## $Abril
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   4.653   0.650  47.400 
## 
## $Fevereiro
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.00    0.00    0.00    3.65    2.85   34.80 
## 
## $Janeiro
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.600   8.532   6.600  59.600 
## 
## $Junho
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   3.573   0.500  30.600 
## 
## $Maio
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   7.406   7.000  48.200 
## 
## $Março
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   3.223   1.200  26.200

Repare que os níveis aparecem em ordem alfabética e não conforme o tempo, alteramos isso com:

levels(clima_lond$Mes)
## [1] "Abril"     "Fevereiro" "Janeiro"   "Junho"     "Maio"      "Março"
# A função match vai indicar a posição dos elementos do primeiro vetor no segundo vetor
pos <- match(c("Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho"), levels(clima_lond$Mes))
pos
## [1] 3 2 6 1 5 4
# Aqui utilizamos as posições obtidas para reordenar os meses nos níveis do fator
clima_lond$Mes = factor(clima_lond$Mes,
                       levels(clima_lond$Mes)[pos])

# Refazendo
tapply(clima_lond$prec.mm, clima_lond$Mes, summary)
## $Janeiro
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.600   8.532   6.600  59.600 
## 
## $Fevereiro
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.00    0.00    0.00    3.65    2.85   34.80 
## 
## $Março
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   3.223   1.200  26.200 
## 
## $Abril
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   4.653   0.650  47.400 
## 
## $Maio
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   7.406   7.000  48.200 
## 
## $Junho
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   0.000   0.000   3.573   0.500  30.600

Podemos também avaliar visualmente através de gráficos:

ggplot(clima_lond) + 
  geom_point(aes(x = Mes, y = prec.mm)) +
  labs(title = "Precipitação x Mês", x = "Meses do ano de 2017", y = "Precipitação em mm")

barplot(tapply(clima_lond$prec.mm, clima_lond$Mes, sum), 
        main="Total Mensal",
        xlab = "Meses do ano de 2017",
        ylab = "Precipitação em mm")

# Vamos fazer um gráfico de barras que mostre a soma de precipitação em cada mês
stat_lond <- tapply(clima_lond$prec.mm, clima_lond$Mes, sum)
str(stat_lond)
##  num [1:6(1d)] 264.5 102.2 99.9 139.6 229.6 ...
##  - attr(*, "dimnames")=List of 1
##   ..$ : chr [1:6] "Janeiro" "Fevereiro" "Março" "Abril" ...
# Repare que o resultado do tapply é um vetor com seus elementos nomeados com cada mês
# Para usar o ggplot nesse caso, precisamos elaborar um data.frame cujas colunas sejam as variáveis que utilizaremos
stat_lond_edit <- data.frame("mes" = factor(names(stat_lond), 
                                            levels = c("Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho")), "soma" = stat_lond)
str(stat_lond_edit)
## 'data.frame':    6 obs. of  2 variables:
##  $ mes : Factor w/ 6 levels "Janeiro","Fevereiro",..: 1 2 3 4 5 6
##  $ soma: num  264.5 102.2 99.9 139.6 229.6 ...
ggplot(stat_lond_edit) +
  geom_bar(aes(x = mes, y = soma), stat="identity") +
  labs(title= "Soma da precipitação por mês", x = "Meses do ano de 2017", y = "Soma da precipitação")

Vamos então realizar uma análise de variância a fim de verificar se há diferenças significativas entre os meses. As funções lm e summary diferem apenas na forma de apresentar os resultados. O p-valor nos indica se podemos considerar diferenças do peso conforme o gênero.

mod <- lm(prec.mm ~ Mes, data = clima_lond)
summary(mod)
## 
## Call:
## lm(formula = prec.mm ~ Mes, data = clima_lond)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -8.532 -4.653 -3.573 -0.950 51.068 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)     8.532      2.054   4.155 5.09e-05 ***
## MesFevereiro   -4.882      2.981  -1.638   0.1033    
## MesMarço       -5.310      2.904  -1.828   0.0692 .  
## MesAbril       -3.879      2.929  -1.325   0.1871    
## MesMaio        -1.126      2.904  -0.388   0.6988    
## MesJunho       -4.959      2.929  -1.693   0.0922 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 11.43 on 175 degrees of freedom
## Multiple R-squared:  0.03264,    Adjusted R-squared:  0.004997 
## F-statistic: 1.181 on 5 and 175 DF,  p-value: 0.3205
modaov <- aov(prec.mm ~ Mes, data = clima_lond)
summary(modaov)
##              Df Sum Sq Mean Sq F value Pr(>F)
## Mes           5    772   154.4   1.181   0.32
## Residuals   175  22881   130.8

Podemos também fazer um teste de médias para diferenciar a precipitação no decorrer dos meses. Aqui utilizaremos o método de Tukey:

tukey.test <- TukeyHSD(x=modaov, 'Mes', conf.level=0.95)
tukey.test
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = prec.mm ~ Mes, data = clima_lond)
## 
## $Mes
##                          diff        lwr       upr     p adj
## Fevereiro-Janeiro -4.88225806 -13.472720  3.708204 0.5747965
## Março-Janeiro     -5.30967742 -13.678889  3.059534 0.4504534
## Abril-Janeiro     -3.87892473 -12.317591  4.559742 0.7710793
## Maio-Janeiro      -1.12580645  -9.495018  7.243405 0.9988508
## Junho-Janeiro     -4.95892473 -13.397591  3.479742 0.5380417
## Março-Fevereiro   -0.42741935  -9.017881  8.163043 0.9999914
## Abril-Fevereiro    1.00333333  -7.654809  9.661476 0.9994427
## Maio-Fevereiro     3.75645161  -4.834010 12.346914 0.8061715
## Junho-Fevereiro   -0.07666667  -8.734809  8.581476 1.0000000
## Abril-Março        1.43075269  -7.007914  9.869419 0.9965219
## Maio-Março         4.18387097  -4.185340 12.553082 0.7022258
## Junho-Março        0.35075269  -8.087914  8.789419 0.9999965
## Maio-Abril         2.75311828  -5.685548 11.191785 0.9355052
## Junho-Abril       -1.08000000  -9.587555  7.427555 0.9991318
## Junho-Maio        -3.83311828 -12.271785  4.605548 0.7798252

Avaliando experimento de café

Agora, trabalharemos com dados de um experimento de café. Acesse aqui:

O experimento trata-se de dados em blocos completos casualizados de 10 progênies de café. Nele a coluna rep refere-se à repetição, prog indica o indivíduo da progênie (prog) e colheita indica a colheita.

data <- read.table("cafe.txt", h = TRUE, sep = "\t", dec = ",")
str(data)
## 'data.frame':    120 obs. of  4 variables:
##  $ rep     : int  1 1 1 1 1 1 1 1 1 1 ...
##  $ prog    : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ colheita: int  1 1 1 1 1 1 1 1 1 1 ...
##  $ prod    : num  4.3 13.2 1.59 2.76 11.38 ...

Não esqueça que é necessário que o arquivo esteja no seu ambiente de trabalho ou que você especifique o caminho completo para que o R o encontre!

Para essa análise de dados, nossa variável resposta é a produção (prod) e a repetição (rep), a progênie (prog) e a colheita (colheita) serão fatores no nosso modelo, identificados por seus níveis.

# Transformar em fator
data$rep <- as.factor(data$rep)
data$prog <- as.factor(data$prog)
data$colheita <- as.factor(data$colheita)
str(data)
## 'data.frame':    120 obs. of  4 variables:
##  $ rep     : Factor w/ 4 levels "1","2","3","4": 1 1 1 1 1 1 1 1 1 1 ...
##  $ prog    : Factor w/ 10 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10 ...
##  $ colheita: Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
##  $ prod    : num  4.3 13.2 1.59 2.76 11.38 ...
# Outra opção
data <- transform(data, rep = factor(rep), prog = factor(prog), colheita = factor(colheita))
str(data)
## 'data.frame':    120 obs. of  4 variables:
##  $ rep     : Factor w/ 4 levels "1","2","3","4": 1 1 1 1 1 1 1 1 1 1 ...
##  $ prog    : Factor w/ 10 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10 ...
##  $ colheita: Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
##  $ prod    : num  4.3 13.2 1.59 2.76 11.38 ...

Vamos analisar somente os dados referentes à primeira colheita. Para isso, podemos obter o subconjunto referente a ela:

# Indexar primeita colheita
Colheita_1 <- subset(data, colheita == 1)
str(Colheita_1)
## 'data.frame':    40 obs. of  4 variables:
##  $ rep     : Factor w/ 4 levels "1","2","3","4": 1 1 1 1 1 1 1 1 1 1 ...
##  $ prog    : Factor w/ 10 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10 ...
##  $ colheita: Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
##  $ prod    : num  4.3 13.2 1.59 2.76 11.38 ...

Repare que, ao fazer o subconjunto, os três níveis do fator colheita ainda são mantidos, embora agora tenhamos apenas um. Isso pode ser um problema para a nossa análise. Portanto, devemos remover os níveis excedentes:

# Droplevels
Colheita_1 <- droplevels(subset(data, colheita == 1))
str(Colheita_1)
## 'data.frame':    40 obs. of  4 variables:
##  $ rep     : Factor w/ 4 levels "1","2","3","4": 1 1 1 1 1 1 1 1 1 1 ...
##  $ prog    : Factor w/ 10 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10 ...
##  $ colheita: Factor w/ 1 level "1": 1 1 1 1 1 1 1 1 1 1 ...
##  $ prod    : num  4.3 13.2 1.59 2.76 11.38 ...

Em seguida, podemos rodar nosso modelo de análise de variância.

# Modelo
Modelo1 <- aov(prod ~ rep + prog,
               contrasts = list(prog = "contr.sum"), 
               data = Colheita_1)
anova(Modelo1)
## Analysis of Variance Table
## 
## Response: prod
##           Df Sum Sq Mean Sq F value   Pr(>F)    
## rep        3  58.90  19.633  2.1836 0.113071    
## prog       9 410.32  45.591  5.0708 0.000475 ***
## Residuals 27 242.75   8.991                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Essa análise variância exige alguns pressupostos, podemos verificar eles nos nossos dados usando:

####################################################
###verificar Pressupostos da análise de variância###
####################################################
names(Modelo1)
##  [1] "coefficients"  "residuals"     "effects"       "rank"         
##  [5] "fitted.values" "assign"        "qr"            "df.residual"  
##  [9] "contrasts"     "xlevels"       "call"          "terms"        
## [13] "model"
Modelo1_residuals <- Modelo1$residuals #armazenando os erros ou resíduos

# teste de Normalidade DOS ERROS##
#---------------------------------#
shapiro.test (Modelo1_residuals) # Hipótese de Nulidade
## 
##  Shapiro-Wilk normality test
## 
## data:  Modelo1_residuals
## W = 0.96494, p-value = 0.2461
# a hipótese de que os erros são normais, nesse caso, como o p-value = 0.24
# ou seja, é maior que >0.05 ou 0.01 (alfa adotado), não se rejeita a hipotese de normalidade 

Vamos trabalhar um poquinho com as informações da ANOVA? Primeiro, guardaremos o valor do quadrado médio:

QME <- anova(Modelo1)["Residuals", "Mean Sq"]
QME
## [1] 8.990907

E a média da primeira colheita da nossa variável resposta (produção):

med <- mean(Colheita_1$prod, na.rm = TRUE)
med
## [1] 8.54525

Com eles podemos calcular o coeficiente de variação (CV):

CVe <- (sqrt(QME)/med)*100
CVe
## [1] 35.08948

Calcule o CVe e QME para a colheita 2

Crie uma função calcular o CVe

Possibilidade de respostas:

CV_E <- function(anova, med){
  QME <- anova(anova)["Residuals", "Mean Sq"]
  CVe <- (sqrt(QME)/med)*100
  
  return(CVe)
}

## 
CV_E(anova = Modelo1, med = med)
## [1] 35.08948

Podemos também calcular a herdabilidade da característica produção:

n_rep <- nlevels(Colheita_1$rep)
VG <- (anova(Modelo1)["prog", "Mean Sq"]- QME)/n_rep
VE <- QME
H_2 <- VG/ (VG + VE)
H_2
## [1] 0.5043871

Crie uma função para estimar a herdabilidade

Criando mapas com ggplot

Não vamos entrar em detalhe sobre os códigos que usamos aqui porque ele faz uso do tidyverse, um pacote que permite manipular os dados com muita flexibilidade, mas ele iria requerer outro curso focado apenas nele! Esta é uma aplicação para mostrar que conseguimos fazer quase tudo com R e ggplot em mãos. O mais difícil é saber manipular os dados…

### Instalar pacotes ###
# devtools::install_github("rpradosiqueira/brazilmaps")
# Need to install 'sf' 
# install.packages("sf")
#  and also the dependencies:
# - 'units' (libudunits2-dev - Linux)
# - 'gdal' (libgdal-dev - Linux)
#
#######################

# Carregar pacote
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.0 ──
## ✓ tibble  3.0.3     ✓ dplyr   1.0.2
## ✓ tidyr   1.1.2     ✓ stringr 1.4.0
## ✓ readr   1.3.1     ✓ forcats 0.5.0
## ✓ purrr   0.3.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(sf)
## Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
# Caso não tenha mais conjunto dados disponível no seu ambiente de trabalho
dados = read.csv("dados_alunos2021.csv", stringsAsFactors = FALSE, dec = ",")

# ou
load("dados_alunos2021.RData")

colnames(dados) = c("Ocupacao", "Graduacao", "Conhecimentos_Genetica", "Conhecimentos_Estatistica", "Conhecimento_Gen_Est", 
                   "Latitude", "Longitude")

# Coletando os dados da base por estado
estados = brazilmaps::get_brmap("State")

# Adicionando uma coluna com as siglas dos estados, será importane para a próxima etapa
estados$sigla = c("RO", "AC", "AM", "RR", "PA", "AP", "TO", "MA", "PI", "CE", "RN", "PB", "PE", "AL", "SE", "BA", "MG", "ES", "RJ", "SP", "PR", "SC", "MS", "MT", "GO", "DF", "RS")

## Aqui buscaremos se as coordenadas das cidades estão contidas nas coordenadas 
## dos estados
inter_sf = st_as_sf(dados, coords = c('Longitude', 'Latitude'), crs = st_crs(estados))

## Mapear coordenadas das cidades nos estados
map_data = st_join(inter_sf, estados %>% 
                     select(sigla, geometry) %>% 
                     mutate(geom_state=geometry)) %>%
  as.data.frame() %>% 
  select(sigla, geom_state)
## although coordinates are longitude/latitude, st_intersects assumes that they are planar
## although coordinates are longitude/latitude, st_intersects assumes that they are planar
# Verificar quantas pessoas por estado 
# Juntar com poligonos dos estados
to_plot = map_data %>%
  group_by(sigla) %>%
  summarise(n = n()) %>%
  right_join(., estados, by=c("sigla"))
## `summarise()` ungrouping output (override with `.groups` argument)
# Aqui usamos um outro tipo de plot, o geom_sf(), que precisa de dados de
# coordenadas geométricas para construir os mapas. O resto envolve apenas
# funções e argumentos do ggplot!
ggplot(to_plot) +
  geom_sf(aes(geometry = geometry, fill = n)) + 
  theme_minimal() + scale_fill_continuous(low = "#C6FFDD", high = "#f64f59", na.value="white") +
  labs(fill = "Número \nde pessoas")

Que tal tentarmos fazer com o mapa mundi?

# Pacotes

# install.packages("rnaturalearth")
# install.packages("rnaturalearthdata")
# install.packages("rgeos")

library("rnaturalearth")
library("rnaturalearthdata")
library("rgeos")
## Loading required package: sp
## rgeos version: 0.5-5, (SVN revision 640)
##  GEOS runtime version: 3.8.0-CAPI-1.13.1 
##  Linking to sp version: 1.4-5 
##  Polygon checking: TRUE
# Mapa mundial
world <- ne_countries(scale = "medium", returnclass = "sf")

## Buscaremos se as coordenadas das cidades estão contidas nas coordenadas 
## dos paises
inter_sf = st_as_sf(dados, coords = c('Longitude', 'Latitude'), crs = st_crs(world))

map_data = st_join(world, inter_sf) %>%
  filter(!is.na(Graduacao)) %>% 
  select(name, geometry) %>% 
  as.data.frame()
## although coordinates are longitude/latitude, st_intersects assumes that they are planar
# Verificar quantas pessoas por país 
# Juntar com poligonos dos países
to_plot = map_data %>%
  group_by(name) %>%
  summarise(n = n()) %>%
  right_join(., world, by=c("name"))
## `summarise()` ungrouping output (override with `.groups` argument)
# Aqui usamos um outro tipo de plot, o geom_sf(), que precisa de dados de
# coordenadas geométricas para construir os mapas. O resto envolve apenas
# funções e argumentos do ggplot!
ggplot(to_plot) +
  geom_sf(aes(geometry = geometry, fill = n)) + 
  theme_minimal() + scale_fill_continuous(low = "#C6FFDD", high = "#f64f59", na.value="white") +
  labs(fill = "Número \nde pessoas")

Família de funções apply

A família de funções apply também podem funcionar como um estrutura de repetição. Sua sintaxe é mais enxuta quando comparada com for ou while e pode facilitar a elaboração do código.

Aqui vamos exemplificar o uso de algumas dessas funções.

apply

A função apply é a base de todas as outras funções da família, portanto a compreensão do funcionamento desta é essencial para entender as demais. Se buscar no help da função, ele indicará que os argumentos da função consistem em: apply(X, MARGIN, FUN, …). Sendo X o conjunto de dados em formato de array (incluindo matrix, que consiste num array de dimensão 2), MARGIN será 1 se a ação deverá ser aplicada à linhas, 2 se for aplicada a colunas e c(1,2) se for aplicada a ambas; FUN é a função que indica ação.

Num simples exemplo temos a matrix:

ex_mat <- matrix(seq(0,21,3), nrow = 2)

Se quisermos somar os elementos das colunas usamos:

apply(ex_mat, 2, sum)
## [1]  3 15 27 39

Se quisermos somar os elementos das linhas:

apply(ex_mat, 1, sum)
## [1] 36 48

Se fossemos utilizar o for para realizar essa tarefa:

# Soma das colunas
for(i in 1:dim(ex_mat)[2]){
  print(sum(ex_mat[,i]))
}
## [1] 3
## [1] 15
## [1] 27
## [1] 39
# Soma das linhas
for(i in 1:dim(ex_mat)[1]){
  print(sum(ex_mat[i,]))
}
## [1] 36
## [1] 48

lapply

Se diferencia do apply por poder receber outros tipos de objetos (mais utilizado com listas) e devolver o resultado em uma lista.

ex_list <- list(A=matrix(seq(0,21,3), nrow = 2), 
                B=matrix(seq(0,14,2), nrow = 2), 
                C= matrix(seq(0,39,5), nrow = 2))
str(ex_list)
## List of 3
##  $ A: num [1:2, 1:4] 0 3 6 9 12 15 18 21
##  $ B: num [1:2, 1:4] 0 2 4 6 8 10 12 14
##  $ C: num [1:2, 1:4] 0 5 10 15 20 25 30 35

Para selecionar a segunda coluna de todas as matrizes

lapply(ex_list, "[", 2)
## $A
## [1] 3
## 
## $B
## [1] 2
## 
## $C
## [1] 5

sapply

A função sapply funciona como o lapply a diferença é que ele retorna apenas um valor por componente da lista e os deposita em um vetor de resposta. Como no exemplo:

sapply(ex_list, "[",1,3)
##  A  B  C 
## 12  8 20

tapply

Esta função é um pouco diferente das demais, ela exige que exista alguma variável categórica (fator) para aplicar ação separadamente conforme suas categorias (levels). Por isso, normalmente é aplicada a data.frames.

Vamos utilizar nosso conjunto de dados:

str(dados)
## 'data.frame':    116 obs. of  7 variables:
##  $ Ocupacao                 : chr  "Doutorado" "Doutorado" "Mestrado" "Outro" ...
##  $ Graduacao                : chr  "Agronomia" "Agronomia" "Biotecnologia" "Licenciatura em Ciências Biológicas" ...
##  $ Conhecimentos_Genetica   : chr  "Avançado" "Avançado" "Intermediário" "Intermediário" ...
##  $ Conhecimentos_Estatistica: chr  "Intermediário" "Intermediário" "Básico" "Intermediário" ...
##  $ Conhecimento_Gen_Est     : chr  "Intermediário" "Intermediário" "0" "Intermediário" ...
##  $ Latitude                 : num  -25.5 -22.7 -15.9 52.1 -22.8 ...
##  $ Longitude                : num  -54.6 -47.6 -48.1 -106.7 -47.7 ...
dados$Graduacao  <- as.factor(dados$Graduacao)

dados[dados == "Avançado"] <- 3
dados[dados == "Intermediário"] <- 2
dados[dados == "Básico"] <- 1
dados[dados == "Sabe o teste F? Fui eu que desenvolvi, mas não publiquei porque sou modesto"] <- 99

dados$Conhecimentos_Genetica <- as.numeric(dados$Conhecimentos_Genetica)

tapply(dados$Conhecimentos_Genetica, dados$Graduacao, mean)
##                                                 Agronomia 
##                                                  2.318182 
##                                                 AGRONOMIA 
##                                                  2.000000 
##                                     Bacharel em Agronomia 
##                                                  2.000000 
##                                                  Biologia 
##                                                  2.571429 
##                                                  Biología 
##                                                  2.000000 
##                                             Biotecnologia 
##                                                  2.600000 
##                                        Ciências bilógicas 
##                                                  3.000000 
##                                       Ciencias Biologicas 
##                                                  2.000000 
##                                       Ciências Biológicas 
##                                                  2.333333 
##                                           Eng. Agronômica 
##                                                  2.000000 
##                                            Eng. Florestal 
##                                                  2.000000 
##                Engeheria em Biotecnologia Vegetal (Chile) 
##                                                  3.000000 
##                                       Engenharia Agrícola 
##                                                  3.000000 
##                                     Engenharia Agronômica 
##                                                  1.800000 
## Engenharia Agronômica / Licenciatura em Ciências Agrárias 
##                                                  2.000000 
##                                 Engenharia Biotecnológica 
##                                                  2.000000 
##                                      Engenharia Florestal 
##                                                  2.000000 
##                                       Engenheiro Agrônomo 
##                                                  2.000000 
##                                      Engenheiro Florestal 
##                                                  1.000000 
##                                              FAEM - UFPEL 
##                                                  2.000000 
##                                   Genética e Melhoramento 
##                                                  2.500000 
##                        Genética e Melhoramento de Plantas 
##                                                  2.500000 
##                       Licenciatura em Ciências Biológicas 
##                                                  2.000000 
##                                     Melhoramento genético 
##                                                  2.000000 
##                                                 Zootecnia 
##                                                  2.000000

Saiba mais sobre essa família de funções no link

Observe que nas funções apply podemos trocar as funções prontas do r base por funções personalizadas.

Se estiver adiantada/o em relação aos colegas, você já pode fazer os exercícios da Sessão extra, se não, faça-os no conforto do seu lar e nos envie dúvidas pelo fórum.

Gerando sorteio para delineamento experimental

Que tal pensarmos em um delineamento experimental e sortearmos as unidades experimentais? Com o pacote agricolae elaboraremos o sorteio de um experimento de blocos completos casualizados.

############################
#SORTEIO DE EXPERIMENTOS####
############################

#install.packages("agricolae")
library(agricolae)
trt <- c("0","1","2","5","10","20","50","100","Dina")
rcbd <- design.rcbd(trt, 6, serie = 1, seed = 1, "default") # seed = 1
rcbd # Planilha de campo
## $parameters
## $parameters$design
## [1] "rcbd"
## 
## $parameters$trt
## [1] "0"    "1"    "2"    "5"    "10"   "20"   "50"   "100"  "Dina"
## 
## $parameters$r
## [1] 6
## 
## $parameters$serie
## [1] 1
## 
## $parameters$seed
## [1] 1
## 
## $parameters$kinds
## [1] "default"
## 
## $parameters[[7]]
## [1] TRUE
## 
## 
## $sketch
##      [,1]   [,2] [,3]   [,4] [,5]   [,6]  [,7]   [,8]   [,9]
## [1,] "Dina" "5"  "50"   "0"  "1"    "20"  "2"    "100"  "10"
## [2,] "1"    "2"  "100"  "0"  "10"   "20"  "Dina" "50"   "5" 
## [3,] "50"   "0"  "Dina" "10" "20"   "100" "5"    "1"    "2" 
## [4,] "10"   "1"  "100"  "20" "0"    "5"   "2"    "Dina" "50"
## [5,] "2"    "20" "1"    "50" "5"    "10"  "100"  "Dina" "0" 
## [6,] "50"   "20" "0"    "5"  "Dina" "2"   "1"    "100"  "10"
## 
## $book
##    plots block  trt
## 1     11     1 Dina
## 2     12     1    5
## 3     13     1   50
## 4     14     1    0
## 5     15     1    1
## 6     16     1   20
## 7     17     1    2
## 8     18     1  100
## 9     19     1   10
## 10    21     2    1
## 11    22     2    2
## 12    23     2  100
## 13    24     2    0
## 14    25     2   10
## 15    26     2   20
## 16    27     2 Dina
## 17    28     2   50
## 18    29     2    5
## 19    31     3   50
## 20    32     3    0
## 21    33     3 Dina
## 22    34     3   10
## 23    35     3   20
## 24    36     3  100
## 25    37     3    5
## 26    38     3    1
## 27    39     3    2
## 28    41     4   10
## 29    42     4    1
## 30    43     4  100
## 31    44     4   20
## 32    45     4    0
## 33    46     4    5
## 34    47     4    2
## 35    48     4 Dina
## 36    49     4   50
## 37    51     5    2
## 38    52     5   20
## 39    53     5    1
## 40    54     5   50
## 41    55     5    5
## 42    56     5   10
## 43    57     5  100
## 44    58     5 Dina
## 45    59     5    0
## 46    61     6   50
## 47    62     6   20
## 48    63     6    0
## 49    64     6    5
## 50    65     6 Dina
## 51    66     6    2
## 52    67     6    1
## 53    68     6  100
## 54    69     6   10

Podemos exportar e salvar nosso sorteio com:

write.table(rcbd,"SORTEIO.txt", row.names=FALSE, sep="\t")
file.show("SORTEIO.txt")
write.csv(rcbd,"SORTEIO.csv",row.names=F)

PCA - Análise de componentes principais

O PCA é uma análise exploratória muito frequente quando utilizada por usuários que possuem muitos dados. Nela, torna-se possível visualizar dados que deveriam ter diversas dimensões em apenas duas componentes mais informativas. Para isto, usamos a função autoplot().

# para instalar, use install.packages("ggfortify")
library(ggfortify)

autoplot(prcomp(~ conhecimentoR + altura + peso + idade, data = dados),
         data = dados, shape = 'area', colour = 'Graduacao', loadings = TRUE, loadings.colour = 'red', 
         loadings.label = TRUE, loadings.label.colour = 'black',
         loadings.label.size = 4) +
  labs(shape = "Área de \ninteresse", color = "Formação", title = "PCA")

# Os parâmetros relacionados com "LOADINGS" são na verdade a direção onde a váriável mais cresce em duas dimensões
# Ela serve apenas como uma aproximação, já que os dados reais precisariam de mais dimensões, que nosso olho não pode ver

Agora que você fez um plot de PCA, você pode perceber que ele é apenas uma variação do geom_point(), isto permite que você adicione todas as camadas de ggplot que você quiser sobre este gráfico. Já fizemos isto com as legendas!

Sugestões, críticas e elogios

Caso tenha sugestões para aprimoramento desse material, enviar e-mail para biometriamarcadores@gmail.com.

Acesse também outros materiais em português produzidos pela mesma equipe aqui.

Este material foi produzido por alunos do programa de pós-graduação em Genética e Melhoramento de Plantas. Cristiane Taniguti, Fernando Correr e e Wellingson Araújo ministraram o Treinamento.

Também recomendamos materiais em inglês aqui.