Aula baseada no livro: Introdução ao R capítulo 3. É sugerida a leitura do livro para um maior aprofundamento na linguagem de programação.
Tudo no R é um objeto. Para atribuirmos resultados de operações a algum objeto que pode posteriormente ser manipulado, usamos a expressão de atribuição “<-”:
y <- 4
y
## [1] 4
x <- "ola"
x
## [1] "ola"
Observações:
Recomenda-se o uso de nomes intuitivos, descritivos.
Nomes de objetos não podem começar com números ou underline
# 2sls <- 45
# _1st_stage <- 1234
O R possui cinco classes básicas ou “atômicas” de objetos:
character;
numeric (números reais);
integer (números inteiros);
complex (números complexos);
logical (Falso/Verdadeiro)
A função class(), aplicada a um objeto, retorna a sua classe.
class(x)
## [1] "character"
x <- 'ola'
class(x)
## [1] "character"
class(y)
## [1] "numeric"
y <- 2L
class(y)
## [1] "integer"
z <- TRUE
class(z)
## [1] "logical"
z <- z == y
class(z)
## [1] "logical"
c <- 1 + 1i
class(c)
## [1] "complex"
NA
, Inf
, -Inf
, e
NaN
1/0
## [1] Inf
-1/0
## [1] -Inf
-Inf
## [1] -Inf
0/0
## [1] NaN
NA
## [1] NA
Podemos testar se uma expressão resulta em um valor especial
is.na(NA_real_)
## [1] TRUE
is.infinite(1/0)
## [1] TRUE
is.nan(0/0)
## [1] TRUE
is.nan(NA_character_)
## [1] FALSE
is.na(0/0)
## [1] TRUE
São um conjunto unidimensional de valores de mesma classe
v <- c("arroz", "feijao")
v
## [1] "arroz" "feijao"
class(v)
## [1] "character"
v <- c(v, 23) # append em um vetor
v
## [1] "arroz" "feijao" "23"
Note que v transformou o numero 23 na string “23” e fez o append. Sem erro!
Vetores possuem tamanho (length)
length(v)
## [1] 3
Podemos usar também o operador :
para criar sequências
numéricas (que são armazenadas como vetores)
z <- 10:30
z
## [1] 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
class(z)
## [1] "integer"
Acessamos os elementos de um vetor através de seu índice
z[2]
## [1] 11
O último elemento de um vetor possui índice igual ao tamanho do vetor
z[length(z)]
## [1] 30
E podemos acessar um subconjunto do vetor através de uma sequência de índices
z[10:length(z)]
## [1] 19 20 21 22 23 24 25 26 27 28 29 30
Índices negativos significam exclusão daquele elemento
z[-1] # retorna z com o primeiro elemento excluído
## [1] 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
z[-c(1:5)] # retorna z sem os primeiros 5 elementos
## [1] 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
Para selecionarmos elementos de um vetor, podemos utilizar também uma expressão lógica, com os operadores == (igual), > (maior), < (menor), >= (maior ou igual), <= (menor ou igual), != (diferente), ou combinações de expressões lógicas por meio dos operadores booleanos “OU” (|), “E” (&), e “Não” (!).
z[z == 15]
## [1] 15
z[z < 15]
## [1] 10 11 12 13 14
z[z %in% c(12, 15, 31)]
## [1] 12 15
z[!(z %in% 15:25)]
## [1] 10 11 12 13 14 26 27 28 29 30
Matrizes são vetores com um atributo de dimensão (dimension), que é ele próprio um vetor inteiro de tamanho 2: número de linhas e número de colunas. Uma matriz é criada por meio da função matrix(). Essa função possui os seguintes argumentos:
data: vetor que contém os valores da matriz;
nrow: número de linhas da matriz;
ncol: número de colunas da matriz;
byrow: indica como a matriz é montada. Se for TRUE, ela é montada linha a linha. Se for FALSE, ela é montada coluna a coluna;
dimnames: nomes das linhas e colunas, respectivamente.
m <- matrix(data = 1:6,
nrow = 2,
ncol = 3,
byrow = TRUE,
dimnames = list(c("trat1", "trat2"), c("out1", "out2", "out3")))
m
## out1 out2 out3
## trat1 1 2 3
## trat2 4 5 6
Para obtermos a dimensão de uma matriz, usamos a função
dim
.
dim(m)
## [1] 2 3
Outra maneira de se criar matrizes é pela adição de linhas ou colunas por meio das funções rbind() e cbind(), respectivamente. rbind() monta uma matriz, empilhando os argumentos linha a linha na ordem em que aparecem na lista. Já cbind() monta a matriz colocando os argumentos lado a lado na ordem em que aparecem na lista.
x <- 1:4
y <- 10:13
rbind(x, y)
## [,1] [,2] [,3] [,4]
## x 1 2 3 4
## y 10 11 12 13
cbind(x, y)
## x y
## [1,] 1 10
## [2,] 2 11
## [3,] 3 12
## [4,] 4 13
Os elementos (células) de uma matriz podem ser acessados por um par de índices que indicam, respectivamente, a linha e a coluna do elemento desejado.
m[2, 3]
## [1] 6
Para extrairmos todos os elementos de uma linha, basta não especificarmos o índice correspondente à coluna.
m[2, ]
## out1 out2 out3
## 4 5 6
m[, 2]
## trat1 trat2
## 2 5
Note que a seleção de uma linha ou coluna retorna um vetor!
Índices negativos excluem os elementos indicados.
m[, -2] # matriz sem a segunda coluna
## out1 out3
## trat1 1 3
## trat2 4 6
Podemos utilizar vetores de índices para selecionarmos uma submatriz.
m[, c(1, 3)]
## out1 out3
## trat1 1 3
## trat2 4 6
Também podemos selecionar elementos de uma matriz através dos nomes das dimensões
m["trat1", "out3"]
## [1] 3
Listas são coleções de elementos que não precisam ser da mesma
classe. As listas são os objetos mais versáteis no R. Os elementos de
uma lista podem ser de qualquer tipo, inclusive outras listas. O tipo
list
é uma importante classe de objetos no R. Listas podem
ser criadas explicitamente usando a função list()
.
x <- list(5, "kiwi", c(FALSE, TRUE, TRUE), 3 + 1i, 2L, m)
x
## [[1]]
## [1] 5
##
## [[2]]
## [1] "kiwi"
##
## [[3]]
## [1] FALSE TRUE TRUE
##
## [[4]]
## [1] 3+1i
##
## [[5]]
## [1] 2
##
## [[6]]
## out1 out2 out3
## trat1 1 2 3
## trat2 4 5 6
class(x)
## [1] "list"
length(x)
## [1] 6
Podemos extrair uma sub-lista usando colchetes simples e índices. Colchetes duplos são utilizados para extrair um elemento da lista. Neste caso o formato de retorno será o do elemento.
x[6] # retorna uma lista com um elemento (a matriz)
## [[1]]
## out1 out2 out3
## trat1 1 2 3
## trat2 4 5 6
x[3:6] # retorno uma lista com os elementos de 3 a 6
## [[1]]
## [1] FALSE TRUE TRUE
##
## [[2]]
## [1] 3+1i
##
## [[3]]
## [1] 2
##
## [[4]]
## out1 out2 out3
## trat1 1 2 3
## trat2 4 5 6
x[[2]] # retorna o character "kiwi"
## [1] "kiwi"
Uma lista pode ser composta de elementos que são eles próprios uma lista ou vetores. Elementos de uma lista que pertence a outra lista são chamados elementos aninhados. Há duas maneiras de acessar um elemento aninhado de uma lista.
x[[c(3, 1)]] # extrai o 1º elemento do vetor que é o 3º elemento da lista
## [1] FALSE
x[[3]][1] # 3º elemento da lista, e então 1º elemento do vetor
## [1] FALSE
Elementos de uma lista podem ser nomeados (assim como em vetores)
x <- list(
num = 5,
char = "kiwi",
vec = c(FALSE, TRUE, TRUE),
comp = 3 + 1i,
int = 2L,
mat = m
)
x
## $num
## [1] 5
##
## $char
## [1] "kiwi"
##
## $vec
## [1] FALSE TRUE TRUE
##
## $comp
## [1] 3+1i
##
## $int
## [1] 2
##
## $mat
## out1 out2 out3
## trat1 1 2 3
## trat2 4 5 6
E agora podemos extrair estes elementos pelo nome
x$vec
## [1] FALSE TRUE TRUE
x[["vec"]]
## [1] FALSE TRUE TRUE
names(x)
## [1] "num" "char" "vec" "comp" "int" "mat"
Data frames são utilizados para armazenar dados tabulados no R. Eles são usualmente criados quando lemos um arquivo de dados para ser analisado. Internamente no R, os data frames são representados como uma lista especial onde cada elemento da lista possui o mesmo tamanho. Cada elemento da lista pode ser interpretado como uma coluna e o tamanho de cada elemento da lista é o número de linhas ou observações. Como se trata de uma lista, as colunas de um data frame não precisam ser da mesma classe.
Um data frame pode ser criado explicitamente por meio da função
data.frame(). Entretanto existem extensão ao data frame do base R, como
por exemplo os tibbles (do pacote tibble
que faz parte do
tidyverse) e o data.table
. Faremos bastante uso deste
último nas aulas práticas.
pacientes <- data.frame(
id = c("P1","P2","P3","P4"),
sexo = c("feminino", "feminino", "masculino", "masculino"),
pad = c(80, 85, 100, 95), pas = c(130, 140, 150, 145)
)
pacientes
## id sexo pad pas
## 1 P1 feminino 80 130
## 2 P2 feminino 85 140
## 3 P3 masculino 100 150
## 4 P4 masculino 95 145
names(pacientes)
## [1] "id" "sexo" "pad" "pas"
Cada coluna em um data.frame é nomeada e representa uma variável.
Os elementos de um data frame podem ser acessados como os elementos de uma lista ou de uma matriz. As variáveis podem ser identificadas pela sua posição no data frame.
pacientes$pad
## [1] 80 85 100 95
pacientes[3, 2]
## [1] "masculino"
pacientes[, c(2, 4)]
## sexo pas
## 1 feminino 130
## 2 feminino 140
## 3 masculino 150
## 4 masculino 145
pacientes[, c("sexo", "pas")]
## sexo pas
## 1 feminino 130
## 2 feminino 140
## 3 masculino 150
## 4 masculino 145
pacientes[, -c(1, 3)]
## sexo pas
## 1 feminino 130
## 2 feminino 140
## 3 masculino 150
## 4 masculino 145
cols <- c("sexo", "pas")
pacientes[, cols]
## sexo pas
## 1 feminino 130
## 2 feminino 140
## 3 masculino 150
## 4 masculino 145
pacientes[pacientes$sexo == "feminino", ]
## id sexo pad pas
## 1 P1 feminino 80 130
## 2 P2 feminino 85 140
Novas funcionalidades são adicionadas ao ambiente por meio da implementação de funções agrupadas em módulos ou pacotes. As funções no R possuem um nome seguido de zero ou mais argumentos entre parênteses. Vejamos alguns exemplos de funções.
x <- c(1, 4, 6, 1, 10) # cria um vetor contendo os números 1, 4, 6, 1 e 10
sort(x, decreasing = TRUE) # ordena x em ordem decrescente
## [1] 10 6 4 1 1
min(x) # menor valor de x
## [1] 1
sum(x)
## [1] 22
prod(x)
## [1] 240
mean(x)
## [1] 4.4
unique(x)
## [1] 1 4 6 10
Podemos também criar nossas próprias funções! Para criarmos uma função, usamos a palavra chave function seguida de uma lista de argumentos formais entre parênteses e separados por vírgulas. O código que é executado cada vez que a função é chamada aparece entre chaves.
twosam <- function(y1, y2) {
n1 <- length(y1)
n2 <- length(y2)
yb1 <- mean(y1)
yb2 <- mean(y2)
s1 <- var(y1)
s2 <- var(y2)
s <- ((n1 - 1)*s1 + (n2 - 1)*s2)/(n1 + n2 - 2)
tst <- (yb1 - yb2)/sqrt(s*(1/n1 + 1/n2))
return(tst)
}
a <- 1:10
b <- 3:12
twosam(a, b)
## [1] -1.477098