1 Breve histórico da linguagem R

R, também conhecida como GNU S, é uma linguagem e um ambiente para computação estatística e gráficos. R implementa um dialeto da linguagem S, desenvolvida pelos laboratórios AT&T Bell. R é um software colaborativo, gratuito e de código aberto.

R é uma linguagem de programação completa e pode ser baixada livremente em https://www.R-project.org. Há implementações para Windows, Unix/Linux, MacOS, etc. Pode-se também baixar o código-fonte de R.

As funcionalidades do R podem ser extendidas através dos diversos pacotes desenvolvidos com os mais diferentes propósitos (regressão beta, genética, redes neurais, modelagem hierárquica, etc.), ou através de implementações desenvolvidas pelo próprio usuário. R é uma linguagem orientada a objetos e sua sintaxe é semelhante a Python e Julia.

2 Bibliografia básica sobre a linguagem R

Há uma variedade grande de livros sobre a linguagem R. Os livros abaixo podem ser usados para consultas:

  • Silva, A. H. A., Cavalcanti, G. A., Pires, J. F. & Terra, M. L. C. “Introdução à Estatística no software R: Estatística Aplicada em Software Livre”, 1ª Ed., Editora UFPB, 2021. Disponível gratuitamente em PDF;
  • Dalgaard, Peter. “Introductory Statistics With R”, 2ª Ed., Springer, 2008;
  • Wickham, Hadley. “R para Data Science: Importe, Arrume, Transforme, Visualize e Modele Dados”, Alta Books, 2019. Versão gratuita (em inglês) disponível online.

O Departamento de Estatística mantém um projeto de extensão que produz materiais e oferece cursos sobre análise estatística utilizando R. O material pode ser encontrado no instagram @estatisticalivre, no canal do Youtube e no agregador.

3 Onde baixar e como instalar R em seu computador

R pode ser baixada libremente em https://www.R-project.org, seguindo a sequência de cliques CRAN, link da localidade, link para o instalador de acordo com o sistema operacional.

Um link direto para a última versão disponível de R para os sistemas operacionais Windows, MacOS e Linux pode ser acessado aqui.

Website da linguagem R
Website da linguagem R

R, no windows, se apresenta como na imagem abaixo.

RGui no sistema operacional Windows
RGui no sistema operacional Windows

Nos sistemas operacionais MacOS e Linux, a interface de R com o usuário é feita através do terminal.

R no Linux
R no Linux

Uma melhor experiência com a linguagem R pode ser obtida utilizando-se outras plataformas de interface com o usuário. O RStudio é a interface mais utilizada por usuários de diversas áreas.

Para além de ser uma plataforma de interface entre R e o usuário, RStudio é uma empresa que oferece serviços de treinamento e suporte em linguagem R e na plataforma RStudio. Diversas bibliotecas de funções de R foram desenvolvidas pela RStudio, dentre as quais, uma “meta-biblioteca” chamada tidyverse, que reúne diversas bibliotecas com diferentes propósitos relacionadas à área de ciência de dados, constituindo um dialeto próprio da linguagem R.

Recentemente, a RStudio iniciou uma série de mudanças e a partir de outubro de 2022 passará se se chamar Posit. As mudanças, contudo, não modificam (pelo menos no curto prazo) a utilização do RStudio.

Website da empresa RStudio
Website da empresa RStudio

Um link direto para a última versão disponível do RStudio para os sistemas operacionais Windows, MacOS e Linux pode ser acessado aqui.

A sequência de instalação deve ser a seguinte:

  • Instale Rde acordo com o seu sistema operacional;
  • Instale o RStudio de acordo com o seu sistema operacional.

Esse link leva para um video no Youtube com instruções simples de como instalar R e RStudio no sistema operacional Windows.

No sistema operacional Linux, o RStudio se apresenta como na figura abaixo. A apresentação em outros sistemas operacionais é muito similar.

RStudio no sistema operacional Linux.

4 Ideias básicas

A utilização mais básica de R é como uma “super calculadora”:

2+2
## [1] 4
5-2
## [1] 3
5*3
## [1] 15
26/2
## [1] 13
log(5)
## [1] 1.609438
log(13, base = 10)
## [1] 1.113943
log10(13)
## [1] 1.113943
exp(-2)
## [1] 0.1353353
3^10
## [1] 59049
pi
## [1] 3.141593
cos(2*pi)
## [1] 1
((3+10)*5)/pi-(2*7+1)
## [1] 5.690143

4.1 Obtendo ajuda

A maneira mais simples de acessar o arquivo de ajuda de uma função é através do comando ?nome_da_função. Por exemplo, ?lm dá acesso à ajuda relativa à função lm, que é usada para ajustar modelos de regressão linear.

De modo similar, podemos usar a função help(). Por exemplo, help(lm) levará ao mesmo resultado que ?lm.

Caso não se conheça o nome da função, pode-se pesquisar um tópico relacionado utilizando a função help.search(). Por exemplo, help.search("epidemiology") fará uma busca de funções e bibliotecas de R relacionadas ao termo epidemiology.

4.2 Objetos, Atribuição de valores e Funções

Objetos em R funcionam como “recipientes” e, como tal, se prestam à tarefa de armazenamento. Quase tudo em R é objeto. A atribuição de valores a objetos é feita através de um dos operadores de atribuição =, <- ou ->.

x = 2
y <- 3
4 -> z

A chamada a um objeto e feita através de seu identificador.

x
## [1] 2
y
## [1] 3
z
## [1] 4

Identificadores (nomes) de objetos podem ser combinações de letras, números, ponto (“.”) e “_”, com a restrição de que não comecem por número. R é”case-sensitive”, isto é, um objeto com identificador a é diferente de um objeto com identificador A, por exemplo. Eu recomendo a utilização do formato snake_case, que separa palavras de letras minúsculas com _. Por exemplo, peso_em_kg, peso_medio, etc.

Operações com objetos são feitas através de operações entre seus identificadores.

x+y+z
## [1] 9
z^y
## [1] 64
z/x
## [1] 2
log(x)
## [1] 0.6931472
exp(-z)
## [1] 0.01831564

Os métodos estatísticos, matemáticos e computacionais estão implementadas em funções (functions). O cálculo de medidas diversas é feito através da passagem de argumentos específicos a essas funções.

Para calcular a média de uma vetor \(x = (2, 3, -1, 5)^\top\), por exemplo, devemos atribuir esses valores a um vetor através da função c() e, em seguida, calcular a média através da função mean():

x = c(2,3,-1,5)
x
## [1]  2  3 -1  5
mean(x)
## [1] 2.25

Exercício: 5 alunos de estatística têm pesos (em Kg) 70, 62, 55, 82 e 77. Calcule o peso médio desses alunos.

Exercício: Para um aluno com peso 55 Kg e altura 162cm, calcule o IMC.

Uma lista resumida de funções importantes é apresentada a seguir.

Função O que retorna
abs(x) o valor absoluto de \(x\)
log(x,b) o logaritmo de \(x\) na base \(b\)
log2(x) o logaritmo de \(x\) na base 2
log10(x) o logaritmo de \(x\) na base 10
log(x) o logaritmo natural de \(x\)
exp(x) \(e^x\)
sin(x) o seno de \(x\)
cos(x) o cosseno de \(x\)
tan(x) a tangente de \(x\)
sinh(x) o seno hiperbólico de \(x\)
cosh(x) o cosseno hiperbólico de \(x\)
tanh(x) a tangente hiperbólica de \(x\)
asin(x) o arcoseno de \(x\)
acos(x) o arcocosseno de \(x\)
atan(x) a arcotangente de \(x\)
asinh(x) o arcoseno hiperbólico de \(x\)
acosh(x) o arcocosseno hiperbólico de \(x\)
atanh(x) a arcotangente hiperbólica de \(x\)
round(x,n) o valor de \(x\) arredondado para \(n\) casas decimais
floor(x) o maior inteiro que é menor ou igual a \(x\)
ceiling(x) o menor inteiro que é maior ou igual a \(x\)
length(x) o número de elementos de um vetor numérico \(x\)
sum(x) a soma dos elementos de um vetor numérico \(x\)
cumsum(x) um vetor com a soma acumulada dos elementos de um vetor numérico \(x\)
prod(x) o produto dos elementos de um vetor numérico \(x\)
cumprod(x) um vetor com o produto acumulado dos elementos de um vetor numérico \(x\)
min(x) a valor mínimo de um vetor numérico \(x\)
max(x) a valor máximo de um vetor numérico \(x\)
mean(x) a média dos elementos de um vetor numérico \(x\)
median(x) a mediana dos elementos de um vetor numérico \(x\)
var(x) a variância dos elementos de um vetor numérico \(x\)
sd(x) o desvio-padrão dos elementos de um vetor numérico \(x\)

4.3 Uso e instalação de bibliotecas

A linguagem R está organizada em bibliotecas de funções (libraries), que ficam disponíveis para o usuário através da instalação de pacotes (packages). Algumas bibliotecas são instaladas junto com a instalação básica de R. Outras precisam ser instaladas pelo usuário. Existem hoje (10/10/2022) 18694 pacotes disponíveis com os mais diversos propósitos que podem ser instalados em R.

As funções library() e require() podem ser utilizadas para carregar as funções de uma biblioteca em R. Para utilizar alguma função da biblioteca MASS, por exemplo, devemos fazer:

library(MASS)

A instalação de uma biblioteca pode ser feita através da função install.packages(). Por exemplo, para instalar a biblioteca e1071, podemos fazer:

install.packages("e1071")

É interessante utilizar o argumento adicional dependencies = TRUE para que bibliotecas as quais a que está sendo instalada depende sejam também instaladas:

install.packages("e1071", dependencies = TRUE)

Para listar todas as bibliotecas que você tem instaladas, use installed.packages() e para atualizar todas as bibliotecas que você tem instaladas, use update.packages(). Para remover um pacote, utilize a função remove.pacakge().

4.4 Constantes, valores ausentes e vetores

Objetos com valor único são denominados constantes. Por exemplo:

x = 3
y = pi
z = TRUE
w = "Análise Estatística"
x
## [1] 3
y
## [1] 3.141593
z
## [1] TRUE
w
## [1] "Análise Estatística"

Valores ausentes (missing values) são representados por NA.

x = c(3, 5, NA, 2)

Vetores são sequências de valores numéricos, de caracteres ou de constantes lógicas (TRUE e FALSE). Podemos utilizar a função interna c() para definir vetores.

pesos = c(60, 72, 57, 90, 95, 72) # vetor numérico
pesos
## [1] 60 72 57 90 95 72
palavras = c("Olá", "alunos", "!") # vetor de strings
palavras
## [1] "Olá"    "alunos" "!"
vetor_logico = c(T, T, F, T, F) # vetor lógico
vetor_logico
## [1]  TRUE  TRUE FALSE  TRUE FALSE

c() pode ser usada também para concatenar vetores. Por exemplo:

x = c(60, 72, 57, 90, 95, 72)
x
## [1] 60 72 57 90 95 72
y = c(70, 82)
y
## [1] 70 82
xy = c(x, y)
xy
## [1] 60 72 57 90 95 72 70 82

Além de c(), outras funções criam vetores (:, seq() e rep()). Por exemplo:

4:10 # sequencia iniciando em 4 e indo até 9, em saltos de tamanho 1
## [1]  4  5  6  7  8  9 10
seq(from = 4, to = 10) # sequencia iniciando em 4 e indo até 10, em saltos de tamanho 1
## [1]  4  5  6  7  8  9 10
seq(from = 4, to = 10, by = 2) # sequencia iniciando em 4 e indo até 10, em saltos de tamanho 2
## [1]  4  6  8 10
seq(4, 10, 2)
## [1]  4  6  8 10
seq(4, 10, length = 30) # sequencia iniciando em 4 e indo até 10, com 30 elementos. O tamanho do salto é calculado automaticamente.
##  [1]  4.000000  4.206897  4.413793  4.620690  4.827586  5.034483  5.241379
##  [8]  5.448276  5.655172  5.862069  6.068966  6.275862  6.482759  6.689655
## [15]  6.896552  7.103448  7.310345  7.517241  7.724138  7.931034  8.137931
## [22]  8.344828  8.551724  8.758621  8.965517  9.172414  9.379310  9.586207
## [29]  9.793103 10.000000
rep(3, 10) # replica o valor 3, 10 vezes
##  [1] 3 3 3 3 3 3 3 3 3 3
rep(c(7, 9, 13), 3) # replica o vetor c(7, 9, 13) 3 vezes
## [1]  7  9 13  7  9 13  7  9 13
rep(c(7, 9, 13), 1:3) # replica as entradas do vetor c(7, 9, 13) 1, 2 e 3 vezes, respectivamente
## [1]  7  9  9 13 13 13
rep(c(7, 9, 13), c(2, 1, 5))
## [1]  7  7  9 13 13 13 13 13
rep(1:3, c(7, 5, 3)) # replica as entradas do vetor c(1, 2, 3) 7, 5 e 3 vezes, respectivamente
##  [1] 1 1 1 1 1 1 1 2 2 2 2 2 3 3 3
rep(c("A", "B", "C"), c(2, 1, 3))
## [1] "A" "A" "B" "C" "C" "C"
rep(c(T, F, T, F), c(3, 2, 1, 4))
##  [1]  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE

4.4.1 Operações com vetores numéricos

Diferentes operações podem ser feitas com vetores, dependendo de seu tipo. Especificamente, com vetores numéricos, podemos proceder operações elemento a elemento, cálculos envolvendo todos os elementos de um vetor e operações entre vetores (algebra vetorial). Considere o vetor a seguir.

pesos = c(60, 72, 57, 90, 95, 72, 85, 74, 65, 91)

A indexação em Rse inicia em 1. Ou seja, o primeiro elemento de uma vetor x é x[1]. Por exemplo:

pesos
##  [1] 60 72 57 90 95 72 85 74 65 91
pesos[1] # 1º elemento
## [1] 60
pesos[length(pesos)] # último elemento
## [1] 91
pesos[-3] # remove o 3º elemento do vetor
## [1] 60 72 90 95 72 85 74 65 91
pesos[3] = 58 # altera o 3º elemento do vetor
pesos[2:5] # "fatia" do vetor do 2º ao 5º elemento
## [1] 72 58 90 95
pesos[c(2,5,7)] # 2º, 5º e 7º elementos
## [1] 72 95 85

Outras operações:

length(pesos) # comprimento do vetor
## [1] 10
is.vector(pesos) # testa se um objeto é um vetor
## [1] TRUE
is.matrix(pesos) # testa se um objeto é uma matriz
## [1] FALSE
is.numeric(pesos) # testa se um objeto é do tipo numérico
## [1] TRUE
is.character(pesos) # testa se um objeto é do tipo string
## [1] FALSE
is.logical(pesos) # testa se um objeto é do tipo lógico
## [1] FALSE
rev(pesos) # Ordem inversa
##  [1] 91 65 74 85 72 95 90 58 72 60
sort(pesos) # Ordenação
##  [1] 58 60 65 72 72 74 85 90 91 95
sort(pesos, decreasing = T) # Ordenação
##  [1] 95 91 90 85 74 72 72 65 60 58
rank(pesos) # ranking
##  [1]  2.0  4.5  1.0  8.0 10.0  4.5  7.0  6.0  3.0  9.0
which.max(pesos) # qual indice corresponde ao valor máximo
## [1] 5
which.min(pesos) # qual indice corresponde ao valor mínimo
## [1] 3

4.4.1.1 Operações elemento a elemento com um vetor numérico

São operações aplicadas a cada elemento do vetor. Por exemplo:

pesos = c(60, 72, 57, 90, 95, 72, 85, 74, 65, 91)
alturas = c(155, 172, 152, 180, 179, 190, 162, 181, 172, 185)
pesos^2
##  [1] 3600 5184 3249 8100 9025 5184 7225 5476 4225 8281
pesos_gramas = pesos*1000
pesos_gramas
##  [1] 60000 72000 57000 90000 95000 72000 85000 74000 65000 91000
imc = pesos/alturas^2
imc
##  [1] 0.002497399 0.002433748 0.002467105 0.002777778 0.002964951 0.001994460
##  [7] 0.003238836 0.002258783 0.002197134 0.002658875

4.4.1.2 Operações com todos os elementos de um ou mais vetores numéricos

Geralmente, envolvem o cálculo de medidas estatísticas de um ou mais vetores. Por exemplo:

pesos = c(60, 72, 57, 90, 95, 72, 85, 74, 65, 91)
alturas = c(155, 172, 152, 180, 179, 190, 162, 181, 172, 185)
mean(pesos) # média dos pesos
## [1] 76.1
mean(alturas) # média das alturas
## [1] 172.8
sd(pesos) # desvio-padrão dos pesos
## [1] 13.48621
sd(alturas) # desvio-padrão das alturas
## [1] 12.77845
cor(pesos, alturas) # correlação linear de Pearson entre os pesos e as alturas
## [1] 0.5874935
pesos%*%pesos # Forma vetorial da soma dos elementos de x ao quadrado
##       [,1]
## [1,] 59549
pesos%*%alturas # Forma vetorial da soma dos elementos de x vezes y
##        [,1]
## [1,] 132412
t(pesos) # Transposto do vetor pesos
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,]   60   72   57   90   95   72   85   74   65    91

Note que a função %*% é usada para multiplicação matricial.

4.4.1.3 Fatores

Fator é o tipo de dado adequado para lidar com variáveis nominais. A função do R para definir uma variável fator é factor():

set.seed(13)
y = sample(0:3, 100, replace = T)
y
##   [1] 3 2 3 0 1 0 1 3 1 3 3 0 3 3 2 0 3 1 2 2 2 0 3 0 1 3 3 3 0 2 0 3 0 2 3 3 2
##  [38] 1 0 0 2 2 2 0 1 3 1 1 0 1 2 3 2 2 1 3 0 3 3 1 1 1 1 2 2 2 0 1 0 1 0 0 3 2
##  [75] 1 0 2 0 1 1 3 0 3 0 3 0 0 2 1 2 0 2 3 2 1 3 2 2 1 3
fy = factor(y, levels = 0:3)
levels(fy) = c("Tipo I", "Tipo II", "Tipo III", "Tipo IV")
fy
##   [1] Tipo IV  Tipo III Tipo IV  Tipo I   Tipo II  Tipo I   Tipo II  Tipo IV 
##   [9] Tipo II  Tipo IV  Tipo IV  Tipo I   Tipo IV  Tipo IV  Tipo III Tipo I  
##  [17] Tipo IV  Tipo II  Tipo III Tipo III Tipo III Tipo I   Tipo IV  Tipo I  
##  [25] Tipo II  Tipo IV  Tipo IV  Tipo IV  Tipo I   Tipo III Tipo I   Tipo IV 
##  [33] Tipo I   Tipo III Tipo IV  Tipo IV  Tipo III Tipo II  Tipo I   Tipo I  
##  [41] Tipo III Tipo III Tipo III Tipo I   Tipo II  Tipo IV  Tipo II  Tipo II 
##  [49] Tipo I   Tipo II  Tipo III Tipo IV  Tipo III Tipo III Tipo II  Tipo IV 
##  [57] Tipo I   Tipo IV  Tipo IV  Tipo II  Tipo II  Tipo II  Tipo II  Tipo III
##  [65] Tipo III Tipo III Tipo I   Tipo II  Tipo I   Tipo II  Tipo I   Tipo I  
##  [73] Tipo IV  Tipo III Tipo II  Tipo I   Tipo III Tipo I   Tipo II  Tipo II 
##  [81] Tipo IV  Tipo I   Tipo IV  Tipo I   Tipo IV  Tipo I   Tipo I   Tipo III
##  [89] Tipo II  Tipo III Tipo I   Tipo III Tipo IV  Tipo III Tipo II  Tipo IV 
##  [97] Tipo III Tipo III Tipo II  Tipo IV 
## Levels: Tipo I Tipo II Tipo III Tipo IV
set.seed(13)
sexo = sample(0:1, 100, replace = T)
sexo
##   [1] 1 0 1 0 1 0 1 1 1 1 1 0 1 1 0 0 1 1 0 0 0 0 1 0 1 1 1 1 0 0 0 1 0 0 1 1 0
##  [38] 1 0 0 0 0 0 0 1 1 1 1 0 1 0 1 0 0 1 1 0 1 1 1 1 1 1 0 0 0 0 1 0 1 0 0 1 0
##  [75] 1 0 0 0 1 1 1 0 1 0 1 0 0 0 1 0 0 0 1 0 1 1 0 0 1 1
sexo = factor(sexo, levels = 0:1)
levels(sexo) = c("F", "M")
sexo
##   [1] M F M F M F M M M M M F M M F F M M F F F F M F M M M M F F F M F F M M F
##  [38] M F F F F F F M M M M F M F M F F M M F M M M M M M F F F F M F M F F M F
##  [75] M F F F M M M F M F M F F F M F F F M F M M F F M M
## Levels: F M

4.5 Matrizes

uma matriz em matemática é apenas um array bi-dimensional de números. Em R, a noção de matriz é extendida a elementos de qualquer tipo, então, dessa forma, você pode ter uma matriz de strings, por exemplo. Uma forma conveniente de criar matrizes é com a função matrix():

matrix(1:12, nrow=3, byrow=T) # Preenchimento por linhas. Ao definir o número de linhas, o número de colunas é calculado automaticamente.
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
matrix(1:12, nrow=3) # O padrão é o preenchimento por colunas.
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12
matrix(1:12, ncol=3) # Ao definir o número de colunas, o número de linhas é calculado automaticamente
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12
matrix(seq(.1,1,.1), nrow=5)
##      [,1] [,2]
## [1,]  0.1  0.6
## [2,]  0.2  0.7
## [3,]  0.3  0.8
## [4,]  0.4  0.9
## [5,]  0.5  1.0
A = matrix(1:12, nrow=3)
A
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12

Para acessar o elemento \((i,j)\) de uma matrix x, faça x[i,j], exemplo:

x = matrix(c(2,-3,1,
             4,2,-5,
             -1,0,2), nrow=3, byrow=T)
x
##      [,1] [,2] [,3]
## [1,]    2   -3    1
## [2,]    4    2   -5
## [3,]   -1    0    2
x[2,3]
## [1] -5
x[2,]
## [1]  4  2 -5
x[,3]
## [1]  1 -5  2
x[2,3] = -4
x
##      [,1] [,2] [,3]
## [1,]    2   -3    1
## [2,]    4    2   -4
## [3,]   -1    0    2

4.5.1 Operações com matrizes numéricas

Da mesma forma que ocorre com os vetores numéricos, as operações com matrizes numéricas podem ser feitas elemento a elemento ou entre matrizes, sendo que estas últimas devem respeitar as restrições impostas pela matemática. Por exemplo:

A = matrix(c(2,-3,1,
             4,2,-5,
             -1,0,2), nrow=3, byrow=T)
A
##      [,1] [,2] [,3]
## [1,]    2   -3    1
## [2,]    4    2   -5
## [3,]   -1    0    2
B = matrix(c(1,-3,2,
             -5,1,4,
             0,-1,2), nrow=3, byrow=T)
B
##      [,1] [,2] [,3]
## [1,]    1   -3    2
## [2,]   -5    1    4
## [3,]    0   -1    2
A+B # Soma ponto a ponto
##      [,1] [,2] [,3]
## [1,]    3   -6    3
## [2,]   -1    3   -1
## [3,]   -1   -1    4
A-B # Subtração ponto a ponto
##      [,1] [,2] [,3]
## [1,]    1    0   -1
## [2,]    9    1   -9
## [3,]   -1    1    0
A*B # Multiplicação ponto a ponto
##      [,1] [,2] [,3]
## [1,]    2    9    2
## [2,]  -20    2  -20
## [3,]    0    0    4
A/B # Divisão ponto a ponto
##      [,1] [,2]  [,3]
## [1,]  2.0    1  0.50
## [2,] -0.8    2 -1.25
## [3,] -Inf    0  1.00
A^2 # Potenciação ponto a ponto
##      [,1] [,2] [,3]
## [1,]    4    9    1
## [2,]   16    4   25
## [3,]    1    0    4
abs(A) # Valor absoluto ponto a ponto
##      [,1] [,2] [,3]
## [1,]    2    3    1
## [2,]    4    2    5
## [3,]    1    0    2
sqrt(abs(B)) # Radiciação ponto a ponto
##          [,1]     [,2]     [,3]
## [1,] 1.000000 1.732051 1.414214
## [2,] 2.236068 1.000000 2.000000
## [3,] 0.000000 1.000000 1.414214
solve(A) # Inversão
##            [,1]      [,2]      [,3]
## [1,]  0.2105263 0.3157895 0.6842105
## [2,] -0.1578947 0.2631579 0.7368421
## [3,]  0.1052632 0.1578947 0.8421053
A%*%B # Multiplicação matricial
##      [,1] [,2] [,3]
## [1,]   17  -10   -6
## [2,]   -6   -5    6
## [3,]   -1    1    2
A%*%solve(B) # Divisão matricial = multiplicação pela inversa
##            [,1]       [,2] [,3]
## [1,]  0.9285714 -0.2142857    0
## [2,] -1.3571429 -1.0714286    1
## [3,] -0.2857143  0.1428571    1
t(A) # Transposta da matriz A
##      [,1] [,2] [,3]
## [1,]    2    4   -1
## [2,]   -3    2    0
## [3,]    1   -5    2
det(A) # Determinante da matriz A
## [1] 19

4.6 Arrays

É a generalização da ideia de matriz para 3 dimensões. É equivalente a ter um vetor de matrizes do mesmo tipo e dimensão. A função de R para arrays é array(). Exemplo:

B = array(NA, dim = c(3, 2, 3)) # Dimensões: linhas x colunas x matrizes
for (i in 1:3) B[,,i] = matrix(rnorm(6), ncol = 2)
B
## , , 1
## 
##            [,1]       [,2]
## [1,]  0.2731292 -0.5461908
## [2,]  0.7555251  0.2343620
## [3,] -0.3490184 -0.2978282
## 
## , , 2
## 
##            [,1]       [,2]
## [1,] -0.8404761  0.6996756
## [2,]  0.8265104 -1.2615742
## [3,]  1.4836912  0.2982717
## 
## , , 3
## 
##            [,1]       [,2]
## [1,] -0.1478071 -0.9205251
## [2,] -0.8889223 -0.5738945
## [3,]  1.0130659  1.1503655

A indexação segue a mesma lógica da indexação de vetores e matrizes. Por exemplo:

B[,,1] # Primeira matriz
##            [,1]       [,2]
## [1,]  0.2731292 -0.5461908
## [2,]  0.7555251  0.2343620
## [3,] -0.3490184 -0.2978282
B[2,,1] # Segunda linha da primeira matrix
## [1] 0.7555251 0.2343620
B[,2,1] # Segunda coluna da primeira matrix
## [1] -0.5461908  0.2343620 -0.2978282
B[1,1,1] # Elemento (1,1) da primeira matriz
## [1] 0.2731292

4.7 Listas

É um conjunto de objetos (possivelmente de tipos e tamanhos diferentes). É a forma como a maioria das funções em R retorna resultados. A função de R para listas é list(). Exemplo:

id = 1:10
pesos = c(60, 72, 57, 90, 95, 72, 85, 74, 65, 91)
sexo = c(0, 1, 1, 1, 0, 0, 0, 1, 0, 0)
sexo = factor(sexo, levels = 0:1)
levels(sexo) = c("F", "M")
x = matrix(rnorm(30), 10, 3)
lista1 = list(titulo = "exemplo", ident = id,
              peso = pesos, sexo = sexo,
              matriz = x)
lista1
## $titulo
## [1] "exemplo"
## 
## $ident
##  [1]  1  2  3  4  5  6  7  8  9 10
## 
## $peso
##  [1] 60 72 57 90 95 72 85 74 65 91
## 
## $sexo
##  [1] F M M M F F F M F F
## Levels: F M
## 
## $matriz
##              [,1]        [,2]       [,3]
##  [1,]  1.14382456  0.44243942  1.6021204
##  [2,] -0.23944276  0.45027946  1.0040690
##  [3,] -1.08680215 -0.07606216  0.3798957
##  [4,] -0.06144699  0.29751322 -0.5655054
##  [5,] -0.51669734 -1.19435471 -1.2137781
##  [6,] -1.90767369 -1.99687548 -1.3643016
##  [7,]  0.10715648  1.38851305 -1.4161330
##  [8,] -1.17737519 -0.08248357 -0.2555780
##  [9,]  1.74542691  0.39251449 -1.2254260
## [10,] -0.39869853 -1.08276971  0.2138343

Para acessar os elementos da lista usamos o $:

lista1$titulo
## [1] "exemplo"
lista1$peso
##  [1] 60 72 57 90 95 72 85 74 65 91
lista1$sexo
##  [1] F M M M F F F M F F
## Levels: F M
lista1$matriz
##              [,1]        [,2]       [,3]
##  [1,]  1.14382456  0.44243942  1.6021204
##  [2,] -0.23944276  0.45027946  1.0040690
##  [3,] -1.08680215 -0.07606216  0.3798957
##  [4,] -0.06144699  0.29751322 -0.5655054
##  [5,] -0.51669734 -1.19435471 -1.2137781
##  [6,] -1.90767369 -1.99687548 -1.3643016
##  [7,]  0.10715648  1.38851305 -1.4161330
##  [8,] -1.17737519 -0.08248357 -0.2555780
##  [9,]  1.74542691  0.39251449 -1.2254260
## [10,] -0.39869853 -1.08276971  0.2138343

A indexação é feita através de [[]]. Por exemplo, para acessar o \(i\)-ésimo elemento de uma lista, faça nomedalista[[i]].

lista1[[1]]
## [1] "exemplo"
lista1[[2]]
##  [1]  1  2  3  4  5  6  7  8  9 10
lista1[[3]]
##  [1] 60 72 57 90 95 72 85 74 65 91
lista1[[4]]
##  [1] F M M M F F F M F F
## Levels: F M
lista1[[5]]
##              [,1]        [,2]       [,3]
##  [1,]  1.14382456  0.44243942  1.6021204
##  [2,] -0.23944276  0.45027946  1.0040690
##  [3,] -1.08680215 -0.07606216  0.3798957
##  [4,] -0.06144699  0.29751322 -0.5655054
##  [5,] -0.51669734 -1.19435471 -1.2137781
##  [6,] -1.90767369 -1.99687548 -1.3643016
##  [7,]  0.10715648  1.38851305 -1.4161330
##  [8,] -1.17737519 -0.08248357 -0.2555780
##  [9,]  1.74542691  0.39251449 -1.2254260
## [10,] -0.39869853 -1.08276971  0.2138343

A função names() retorna os nomes dos objetos de uma lista.

names(lista1)
## [1] "titulo" "ident"  "peso"   "sexo"   "matriz"

4.8 Indexação condicional

Frequentemente estaremos interessados em selecionar observações segundo algum critério ou “filtrar” observações. Isso pode ser realizado em R através de indexação condicional com a utilização de operadores de comparação e operadores lógicos.

4.8.1 Operadores de comparação

Também conhecidos como operadores relacionais, esses operadores permitem estabelecer a relação entre dois valores de entrada, retornando um valor lógico TRUE ou FALSE. Os operadores de comparação em R são:

Operador Significado
== igual a
!= diferente de
< menor que
> maior que
<= menor ou igual a
>= maior ou igual a
%in% pertence a

Exemplos:

1 == 1
## [1] TRUE
1 != 1
## [1] FALSE
1 != 2
## [1] TRUE
1 < 2
## [1] TRUE
1 > 2
## [1] FALSE
2 <= c(1,3,5,7,9)
## [1] FALSE  TRUE  TRUE  TRUE  TRUE
c(1,3,5,7,9) > 2
## [1] FALSE  TRUE  TRUE  TRUE  TRUE
c(1,3,5,7,9) >= c(2,1,3,9,7)
## [1] FALSE  TRUE  TRUE FALSE  TRUE
5 %in% c(2,1,3,9,7)
## [1] FALSE
c(7,2,5) %in% c(2,1,3,9,7)
## [1]  TRUE  TRUE FALSE
"b" %in% c("a","s","d","f","g")
## [1] FALSE
c("a","b") %in% c("a","s","d","f","g")
## [1]  TRUE FALSE

4.8.2 Operadores lógicos

Esses operadores combinam multiplas condições relacionais retornando um valor lógico TRUE ou FALSE. Os operadores lógicos em R são:

Operador Significado
& AND (E) lógico
| OR (OU) lógico
! NOT (NÃO) lógico
xor Exclusive OR (OU Exclusivo)

As combinações de acordo com cada operador estão descritas na tabela a seguir.

A B A & B A | B !A !B xor(A,B)
TRUE TRUE TRUE TRUE FALSE FALSE FALSE
TRUE FALSE FALSE TRUE FALSE TRUE TRUE
FALSE TRUE FALSE TRUE TRUE FALSE TRUE
FALSE FALSE FALSE FALSE TRUE TRUE FALSE

Exemplos:

1 == 1 & 2 > 1
## [1] TRUE
1 == 1 & 2 < 1
## [1] FALSE
1 != 1 & 2 > 1
## [1] FALSE
1 != 1 & 2 < 1
## [1] FALSE
1 == 1 | 2 > 1
## [1] TRUE
1 == 1 | 2 < 1
## [1] TRUE
1 != 1 | 2 > 1
## [1] TRUE
1 != 1 | 2 < 1
## [1] FALSE
!(1 == 1)
## [1] FALSE
!(1 != 1)
## [1] TRUE
xor((1 == 1),(2 > 1))
## [1] FALSE
xor((1 == 1),(2 < 1))
## [1] TRUE
xor((1 != 1),(2 > 1))
## [1] TRUE
xor((1 != 1),(2 < 1))
## [1] FALSE

4.9 Data frames

Em análise estatística de dados é frequente que os dados sejam armazenados em formato tabular. Alguns conceitos precisam ser introduzidos:

  • Uma variável é uma quantidade, qualidade ou propriedade que pode ser medida;
  • Um valor é o estado de uma variável quando é realizada a medida;
  • Uma observação (caso, exemplo, indivíduo, etc.) é um conjunto de medidas feitas sob condições similares. Uma observação conterá diversos valores, cada um associado a uma variável diferente;
  • Dado tabular é um conjunto de valores, cada um associado a uma variável e uma observação. Os dados tabulares estão arrumados se cada valor estiver em sua própria “célula”, cada variável em sua própria coluna e cada observação em sua própria linha.

Em R, dados tabulares são armazenados como data frames. Um data frame pode ser visto como uma matriz que aceita tipos diferentes de variáveis (numéricas, fatores, lógicas, caracteres, etc.).

A função em R para criar data frames é data.frame(). Por exemplo:

id = 1:10
pesos = c(60, 72, 57, 90, 95, 72, 85, 74, 65, 91)
alturas = c(155, 172, 152, 180, 179, 190, 162, 181, 172, 185)
sexo = c(0, 1, 1, 1, 0, 0, 0, 1, 0, 0)
sexo = factor(sexo, levels = 0:1)
levels(sexo) = c("F", "M")
df = data.frame(id = id, peso = pesos, altura = alturas, sexo = sexo)
df
##    id peso altura sexo
## 1   1   60    155    F
## 2   2   72    172    M
## 3   3   57    152    M
## 4   4   90    180    M
## 5   5   95    179    F
## 6   6   72    190    F
## 7   7   85    162    F
## 8   8   74    181    M
## 9   9   65    172    F
## 10 10   91    185    F

O acesso às colunas de uma data frame é feito de modo similar ao acesso aos abjetos de uma lista. Por exemplo:

df$id
##  [1]  1  2  3  4  5  6  7  8  9 10
df$peso
##  [1] 60 72 57 90 95 72 85 74 65 91
df$altura
##  [1] 155 172 152 180 179 190 162 181 172 185
df$sexo
##  [1] F M M M F F F M F F
## Levels: F M

Ou, equivalentemente:

df[[1]]
##  [1]  1  2  3  4  5  6  7  8  9 10
df[[2]]
##  [1] 60 72 57 90 95 72 85 74 65 91
df[[3]]
##  [1] 155 172 152 180 179 190 162 181 172 185
df[[4]]
##  [1] F M M M F F F M F F
## Levels: F M

Além disso, indexação similar à utilizada com matrizes também pode ser utilizada com data frames. Por exemplo:

df[3,]
##   id peso altura sexo
## 3  3   57    152    M
df[,3]
##  [1] 155 172 152 180 179 190 162 181 172 185
df[3,3]
## [1] 152
df[2:5,]
##   id peso altura sexo
## 2  2   72    172    M
## 3  3   57    152    M
## 4  4   90    180    M
## 5  5   95    179    F
df[,2:3]
##    peso altura
## 1    60    155
## 2    72    172
## 3    57    152
## 4    90    180
## 5    95    179
## 6    72    190
## 7    85    162
## 8    74    181
## 9    65    172
## 10   91    185
df[2:5,2:3]
##   peso altura
## 2   72    172
## 3   57    152
## 4   90    180
## 5   95    179

A indexação das colunas também pode ser feita utilizando os nomes das variáveis. Por exemplo:

df[,"peso"]
##  [1] 60 72 57 90 95 72 85 74 65 91
df[,c("peso","sexo")]
##    peso sexo
## 1    60    F
## 2    72    M
## 3    57    M
## 4    90    M
## 5    95    F
## 6    72    F
## 7    85    F
## 8    74    M
## 9    65    F
## 10   91    F

4.9.1 Leitura de arquivos externos

Frequentemente os dados de um estudo são armazenados no formato tabular em planilhas ou arquivos de texto. A leitura desses conjuntos de dados em R depende da forma como os dados estão escritos nos arquivos. Algumas considerações a serem feitas (dentre muitas possíveis) são:

  • Onde está o arquivo de dados?
  • Qual a extensão do arquivo?
  • Há um “cabeçalho” no meu arquivo de dados com os nomes das colunas?
  • Como as colunas estão separadas ou delimitadas no arquivo (espaço, vírgula, ponto-e-vírgula, tabulação, etc)?
  • Há valores ausentes e como estes estão representados?
  • Qual separador decimal foi utilizado?

R dispõe de diversas funções nativas para leitura de arquivos de dados armazenados como texto (.txt, .dat, .csv, .data, etc.). Além disso, há diversas bibliotecas para leitura de arquivos armazenados em planilhas do Microsoft Excel (.xlsx) ou oriundos de outros programas, como o IBM SPSS (.sav), por exemplo.

4.9.1.1 Diretório de trabalho

A função getwd() retorna o diretório de trabalho atual. Para definir um novo diretório de trabalho usamos a função setwd(). Por exemplo:

# Em Sistemas operacionais Linux:
# setwd("/home/marcelo/Dropbox/DE-UFPB/disciplinas/PPGMDS/2025-1/ALC/MDSA000019")
# Em Sistemas operacionais Windows:
# setwd("C:\\Users\\marcelo\\Dropbox\\DE-UFPB\\disciplinas\\PPGMDS\\2025-1\\ALC\\MDSA000019")
# Em Sistemas operacionais macOS:
setwd("/Users/marceloferreira/Dropbox/DE-UFPB/disciplinas/PPGMDS/2025-1/ALC/MDSA000019")

4.9.1.2 Leitura e escrita de arquivos de texto

A função read.table() lê arquivos de texto (.txt, .dat, .csv, .data, etc.) com dados escritos no formato tabular e cria um data frame a partir dele.

read.table(file, header = FALSE, sep = "", quote = "\"'",
           dec = ".", numerals = c("allow.loss", "warn.loss", "no.loss"),
           row.names, col.names, as.is = !stringsAsFactors,
           na.strings = "NA", colClasses = NA, nrows = -1,
           skip = 0, check.names = TRUE, fill = !blank.lines.skip,
           strip.white = FALSE, blank.lines.skip = TRUE,
           comment.char = "#",
           allowEscapes = FALSE, flush = FALSE,
           stringsAsFactors = FALSE,
           fileEncoding = "", encoding = "unknown", text, skipNul = FALSE)

Seus principais argumentos são:

  • file: Arquivo a ser lido. Caso não seja especificado o caminho completo para o arquivo, este será relativo ao diretório de trabalho atual. Alternativamente, file pode ser um endereço da internet (URL);
  • header: Valor lógico indicando se o arquivo contém os nomes das variáveis na primeira linha. O valor padrão é header = FALSE;
  • sep: O caracter delimitador de campo. O valor padrão é sep = "" (“espaço em branco”);
  • dec: O caracter utilizado como separador decimal. O valor padrão é dec = ".";
  • na.strings: Um vetor de strings que devem ser interpretadas como valores ausentes (NA). O valor padrão é na.strings = "NA";
  • stringsAsFactors: valor lógico indicando se vetores de caracteres devem ser convertidos para fatores.

Para uma descrição completa de todos os argumentos de read.table(), faça ?read.table.

Por exemplo, vamos fazer a leitura do arquivo heart_disease_a.txt, disponível no SIGAA. O arquivo tem seus campos delimitados por vírgula, possui cabeçalho na primeira linha, utiliza ponto como separador decimal e tem os valores ausentes representados por NA.

Imagem do arquivo heart_disease_a.txt
Imagem do arquivo heart_disease_a.txt

Se o arquivo estiver salvo no diretório de trabalho atual, para lê-lo e armazená-lo em um objeto identificado por df, basta fazer:

df = read.table("heart_disease_a.txt", header = TRUE, sep = ",")

Se o arquivo não estiver salvo no diretório de trabalho atual, para lê-lo e armazená-lo em um objeto identificado por df é necessário especificar o caminho completo:

df = read.table("/home/marcelo/Dropbox/DE-UFPB/disciplinas/2022-1/MDSA000019/heart_disease_a.txt", header = TRUE, sep = ",")

Para visualizar as primeiras 10 linhas do conjunto de dados, utilizamos a função head(). Por exemplo:

head(df, 10)
##    sex age current_smoker cigs_per_day bp_meds prevalent_stroke prevalent_hyp
## 1    1  39              0            0       0                0             0
## 2    0  46              0            0       0                0             0
## 3    1  48              1           20       0                0             0
## 4    0  61              1           30       0                0             1
## 5    0  46              1           23       0                0             0
## 6    0  43              0            0       0                0             1
## 7    0  63              0            0       0                0             0
## 8    0  45              1           20       0                0             0
## 9    1  52              0            0       0                0             1
## 10   1  43              1           30       0                0             1
##    diabetes tot_chol sys_bp dia_bp   bmi heart_rate glucose ten_year_chd
## 1         0      195  106.0     70 26.97         80      77            0
## 2         0      250  121.0     81 28.73         95      76            0
## 3         0      245  127.5     80 25.34         75      70            0
## 4         0      225  150.0     95 28.58         65     103            1
## 5         0      285  130.0     84 23.10         85      85            0
## 6         0      228  180.0    110 30.30         77      99            0
## 7         0      205  138.0     71 33.11         60      85            1
## 8         0      313  100.0     71 21.68         79      78            0
## 9         0      260  141.5     89 26.36         76      79            0
## 10        0      225  162.0    107 23.61         93      88            0

A função dim() retorna o número de linhas (tamanho da amostra) e de colunas (número de variáveis) do conjunto de dados:

dim(df)
## [1] 4238   15

Este conjunto de dados é referente a um estudo com 4238 indivíduos sobre doenças cardiovasculares na cidade de Framingham, Massachusetts, EUA. As 15 variáveis disponíveis são:

  • sex: sexo (0 - Feminino, 1 - Masculino);
  • age: idade (a idade dos indivíduos, em anos);
  • current_smoker: fumante (0 - Não, 1 - Sim);
  • cigs_per_day: número de cigarros por dia;
  • bp_meds: uso de medicamentos para hipertensão (0 - Não, 1 - Sim);
  • prevalent_stroke: acidente vascular cerebral (AVC) prévio (0 - Não, 1 - Sim);
  • prevalent_hyp: hipertensão (0 - Não, 1 - Sim);
  • diabetes: diabetes (0 - Não, 1 - Sim);
  • tot_chol: nível de colesterol total;
  • sys_bp: pressão sistólica;
  • dia_bp: pressão diastólica;
  • bmi: índice de massa corporal (imc);
  • heart_rate: frequência cardíaca;
  • glucose: nível de glicose;
  • ten_year_chd: risco de doença cardíaca em um período de 10 anos (0 - Não, 1 - Sim).

A função read.csv() é utilizada para ler arquivos com extensão .csv. Sua sintaxe é similar à de read.table() com a diferença de que, por padrão, temos header = TRUE e sep = ",".

read.csv(file, header = TRUE, sep = ",", quote = "\"",
         dec = ".", fill = TRUE, comment.char = "", ...)

Outras funções úteis para leitura de arquivos texto são read.csv2(), read.delim() e read.delim2().

Exercício: Utilize as funções read.table() e read.csv() para ler os arquivos heart_disease_b.txt e heart_disease_c.csv disponíveis no SIGAA.

Exercício: Estude e entenda o funcionamento das funções read.csv2(), read.delim() e read.delim2().

A função write.table() é utilizada para escrever um conjunto de dados como um arquivo texto.

write.table(x, file = "", append = FALSE, quote = TRUE, sep = " ",
            eol = "\n", na = "NA", dec = ".", row.names = TRUE,
            col.names = TRUE, qmethod = c("escape", "double"),
            fileEncoding = "")

Por exemplo, para escrever o objeto df em um arquivo de texto com o nome heart_disease_d.txt, em que os campos são delimitados por ";", podemos fazer:

write.table(df, "heart_disease_d.txt", quote = FALSE, sep = ";", row.names = FALSE)

A função write.csv() tem sintaxe semelhante à de write.table(), mas usa, por padrão, vírgula como delimitador de campo.

Existem diversas bibliotecas de R para leitura de arquivos com diferentes extensões como, por exemplo, .xlsx (Microsoft Excel), .sav (IBM SPSS), dentre outras. Contudo, arquivos com quaisquer extensões podem ser convertidos em arquivos de texto e lidos em R utilizando suas funções nativas.

4.10 Fluxo de trabalho: scripts

É recomendável agrupar e organizar seu código de R em scripts. Scripts de R são basicamente arquivos de texto com a extensão .r. Para criar um novo script, clique no menu File, selecione New File e, em seguida, R script. Alternativamente, use o atalho do teclado Shift+Ctrl+N em sistemas operacionais Linux ou Microsoft Windows, ou Shift+Cmd+N em sistemas operacionais macOS.

Para executar a linha em que está posicionado o cursor no script ou trecho de código selecionado, faça Ctrl+Enter em sistemas operacionais Linux ou Microsoft Windows, ou Cmd+Enter em sistemas operacionais macOS. Ao executar uma linha ou trecho de código selecionado o cursor será movido para a próxima em que existe código válido. A combinação Shift+Ctrl+S em sistemas operacionais Linux ou Microsoft Windows, ou Shift+Cmd+S em sistemas operacionais macOS, executa todo o script em um único passo.