As funções no R são definidas como:
nome(argumento1, argumento2, ...)
Exemplo: função runif()
(para gerar valores aleatórios de uma distribuição uniforme):
runif(n, min = 0, max = 1)
runif(10, 1, 100)
## [1] 31.468845 26.509578 55.679921 6.581932 47.386379 48.893303 81.427859
## [8] 37.661733 55.109301 17.855943
Argumentos que já possuem um valor especificado (como max
e min
) podem ser omitidos:
runif(10)
Se os argumentos forem nomeados, a ordem deles dentro da função não tem mais importância:
runif(min = 1, max = 100, n = 10)
Argumentos nomeados e não nomeados podem ser utilizados, desde que os não nomeados estejam na posição correta:
runif(10, max = 100, min = 1)
Exemplo: função sample()
:
sample(x, size, replace = FALSE, prob = NULL)
x
e size
devem ser obrigatoriamente especificadosreplace
é lógico: TRUE
(T
) ou FALSE
(F
)prob
é um argumento vazio ou ausente (“opcional”)Exemplo: função plot()
:
plot(x, y, ...)
...
” permite especificar argumentos de outras funções (por exemplo par()
)Argumentos e detalhes do funcionamento das funções:
?runif
ou
help(runif)
A documentação contém os campos:
Procura por funções que contenham palavra
:
help.search("palavra")
Ajuda através do navegador (também contém manuais, …):
help.start()
Busca por palavra
nos arquivos da lista de discussão do R:
RSiteSearch("palavra")
A ideia original do R é transformar usuários em programadores
Criar funções para realizar trabalhos específicos é um dos grandes poderes do R
Por exemplo, podemos criar a famosa função
ola.mundo <- function(){
writeLines("Olá mundo")
}
E chama-la através de
ola.mundo()
## Olá mundo
A função acima não permite alterar o resultado de saída. Podemos fazer isso incluindo um argumento
ola.mundo <- function(texto){
writeLines(texto)
}
E fazer por exemplo
ola.mundo("Funções são legais")
## Funções são legais
(Veremos detalhes de funções mais adiante)
runif()
gere \(30\) números aleatórios entre:
"+"
x
e y
O que é um objeto?
Por quê objetos?
Programação:
“Tudo no R é um objeto.”
“Todo objeto no R tem uma classe”
summary()
plot()
Veja o resultado de
methods(summary)
methods(plot)
A variável x
recebe o valor \(2\) (tornando-se um objeto dentro do R):
x <- 2
O símbolo
<-
é chamado de operador de atribuição. Ele serve para atribuir valores a objetos, e é formado pelos símbolos<
e-
, obrigatoriamente sem espaços.
Para ver o conteúdo do objeto:
x
## [1] 2
Observação: O símbolo
=
pode ser usado no lugar de<-
mas não é recomendado.
Quando você faz
x <- 2
está fazendo uma declaração, ou seja, declarando que a variável x
irá agora se tornar um objeto que armazena o número 2
. As declarações podem ser feitas uma em cada linha
x <- 2
y <- 4
ou separadas por ;
x <- 2; y <- 4
Operações matemáticas em objetos:
x + x
## [1] 4
Objetos podem armazenar diferentes estruturas de dados:
y <- runif(10)
y
## [1] 0.6249965 0.8821655 0.2803538 0.3984879 0.7625511 0.6690217 0.2046122
## [8] 0.3575249 0.3594751 0.6902905
Note que cada objeto só pode armazenar uma estrutura (um número ou uma sequência de valores) de cada vez! (Aqui, o valor \(4\) que estava armazenado em y
foi sobrescrito pelos valores acima.)
_
”, e “.
”
c q t C D F I T diff df data var pt
dados
\(\neq\)Dados
\(\neq\)DADOS
Liste os objetos criados com a função ls()
:
ls()
Para remover apenas um objeto:
rm(x)
Para remover outros objetos:
rm(x, y)
Para remover todos os objetos:
rm(list = ls())
Cuidado! O comando acima apaga todos os objetos na sua área de trabalho sem perguntar. Depois só é possível recuperar os objetos ao rodar os script novamente.
x
x
por \(345\) e armazene em y
y
O R possui 5 classes básicas de objetos, também chamados de objetos “atômicos”:
character
numeric
integer
complex
logical
Um vetor só pode conter elementos de uma mesma classe
(A única excessão é a lista).
Características:
Usando a função c()
para criar vetores:
num <- c(10, 5, 2, 4, 8, 9)
num
## [1] 10 5 2 4 8 9
class(num)
## [1] "numeric"
Por que numeric
e não integer
?
x <- c(10L, 5L, 2L, 4L, 8L, 9L)
x
## [1] 10 5 2 4 8 9
class(x)
## [1] "integer"
Para forçar a representação de um número para inteiro é necessário usar o sufixo L
.
Note que a diferença entre numeric
e integer
também possui impacto computacional, pois o armazenamento de números inteiros ocupa menos espaço na memória. Dessa forma, esperamos que o vetor x
acima ocupe menos espaço na memória do que o vetor num
, embora sejam aparentemente idênticos. Veja:
object.size(num)
## 88 bytes
object.size(x)
## 72 bytes
A diferença pode parecer pequena, mas pode ter um grande impacto computacional quando os vetores são formados por milhares ou milhões de números.
Os números que aparecem na tela do console do R são apenas representações simplificadas do número real armazenado na memória. Por exemplo,
x <- runif(10)
x
## [1] 0.2875775 0.7883051 0.4089769 0.8830174 0.9404673 0.0455565 0.5281055
## [8] 0.8924190 0.5514350 0.4566147
O objeto x
contém números como 0.2875775, 0.7883051, etc, que possuem 7 casas decimais, que é o padrão do R. O número de casas decimais é controlado pelo argumento digits
da função options
. Para visualizar essa opção, use
getOption("digits")
## [1] 7
Note que esse valor de 7 é o número de dígitos significativos, e pode variar conforme a sequência de números. Por exemplo,
y <- runif(10)
y
## [1] 0.069360916 0.817775199 0.942621732 0.269381876 0.169348123
## [6] 0.033895622 0.178785004 0.641665366 0.022877743 0.008324827
possui valores com 9 casas decimais. Isto é apenas a representação do número que aparece na tela. Internamente, cada número é armazenado com uma precisão de 22 casas decimais! Você pode ver o número com toda sua precisão usando a função print()
e especificando o número de casas decimais com o argumento digits
(de 1 a 22)
print(x, digits = 1)
## [1] 0.29 0.79 0.41 0.88 0.94 0.05 0.53 0.89 0.55 0.46
print(x, digits = 7) # padrão
## [1] 0.2875775 0.7883051 0.4089769 0.8830174 0.9404673 0.0455565 0.5281055
## [8] 0.8924190 0.5514350 0.4566147
print(x, digits = 22)
## [1] 0.28757752012461423873901 0.78830513544380664825439
## [3] 0.40897692181169986724854 0.88301740400493144989014
## [5] 0.94046728429384529590607 0.04555649938993155956268
## [7] 0.52810548804700374603271 0.89241904439404606819153
## [9] 0.55143501446582376956940 0.45661473530344665050507
Também é possível alterar a representação na tela para o formato científico, usando a função format()
format(x, scientific = TRUE)
## [1] "2.875775e-01" "7.883051e-01" "4.089769e-01" "8.830174e-01"
## [5] "9.404673e-01" "4.555650e-02" "5.281055e-01" "8.924190e-01"
## [9] "5.514350e-01" "4.566147e-01"
Nessa representação, o valor 2.875775e-01 = \(2.875775 \times 10^{-01}\) = 0.2875775.
Usando a função seq()
seq(1, 10)
## [1] 1 2 3 4 5 6 7 8 9 10
Ou 1:10
gera o mesmo resultado. Para a sequência variar em \(2\)
seq(from = 1, to = 10, by = 2)
## [1] 1 3 5 7 9
Para obter \(15\) valores entre \(1\) e \(10\)
seq(from = 1, to = 10, length.out = 15)
## [1] 1.000000 1.642857 2.285714 2.928571 3.571429 4.214286 4.857143
## [8] 5.500000 6.142857 6.785714 7.428571 8.071429 8.714286 9.357143
## [15] 10.000000
Usando a função rep()
rep(1, 10)
## [1] 1 1 1 1 1 1 1 1 1 1
Para gerar um sequência várias vezes
rep(c(1, 2, 3), 5)
## [1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
Para repetir um número da sequência várias vezes
rep(c(1, 2, 3), each = 5)
## [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
Operações podem ser feitas entre um vetor e um número:
num * 2
## [1] 20 10 4 8 16 18
E também entre vetores de mesmo comprimento ou com comprimentos múltiplos:
num * num
## [1] 100 25 4 16 64 81
num + c(2, 4, 1)
## [1] 12 9 3 6 12 10
Agora tente:
num + c(2, 4, 1, 3)
Os objetos possuem atributos, que servem para descrever o formato do objeto:
names
, dimnames
length
dim
class
Classe:
class(num)
## [1] "numeric"
Comprimento:
length(num)
## [1] 6
Vetores também podem ter outras classes:
caracter <- c("brava", "joaquina", "armação")
caracter
## [1] "brava" "joaquina" "armação"
logico <- caracter == "armação"
logico
## [1] FALSE FALSE TRUE
ou
logico <- num > 4
logico
## [1] TRUE TRUE FALSE FALSE TRUE TRUE
No exemplo anterior, a condição num > 4
é uma expressão condicional, e o símbolo >
um operador lógico. Os operadores lógicos utilizados no R são:
< |
menor |
<= |
menor igual |
> |
maior |
>= |
maior igual |
== |
igual |
!= |
diferente |
& |
e |
| |
ou |
Características:
Utilizando as funções factor()
e c()
:
fator <- factor(c("alta","baixa","baixa","media",
"alta","media","baixa","media","media"))
fator
## [1] alta baixa baixa media alta media baixa media media
## Levels: alta baixa media
class(fator)
## [1] "factor"
Caso haja uma hierarquia, os níveis dos fatores podem ser ordenados:
fator <- factor(c("alta","baixa","baixa","media",
"alta","media","baixa","media","media"),
levels = c("alta","media","baixa"))
fator
## [1] alta baixa baixa media alta media baixa media media
## Levels: alta media baixa
A
, B
, e C
, repetidas cada uma 15, 12, e 8 vezes, respectivamente.B
nesse objeto.sum()
e descubra como fazer para contar o número de letras B
neste vetor (usando sum()
).Algumas vezes isso acontece por acidente, mas também pode acontecer de propósito.
O que acontece aqui?
w <- c(5L, "a")
x <- c(1.7, "a")
y <- c(TRUE, 2)
z <- c("a", T)
Lembre-se da regra:
Um vetor só pode conter elementos de uma mesma classe
Quando objetos de diferentes classes são misturados, ocorre a coerção, para que cada elemento possua a mesma classe.
Nos exemplos acima, nós vemos o efeito da coerção implícita, quando o R tenta representar todos os objetos de uma única forma.
Nós podemos forçar um objeto a mudar de classe, através da coerção explícita, realizada pelas funções as.*
:
x <- 0:6
class(x)
## [1] "integer"
as.numeric(x)
## [1] 0 1 2 3 4 5 6
as.logical(x)
## [1] FALSE TRUE TRUE TRUE TRUE TRUE TRUE
as.character(x)
## [1] "0" "1" "2" "3" "4" "5" "6"
as.factor(x)
## [1] 0 1 2 3 4 5 6
## Levels: 0 1 2 3 4 5 6
De ?logical
:
Logical vectors are coerced to integer vectors in contexts where a
numerical value is required, with ‘TRUE’ being mapped to ‘1L’,
‘FALSE’ to ‘0L’ and ‘NA’ to ‘NA_integer_’.
(x <- c(FALSE, TRUE))
## [1] FALSE TRUE
class(x)
## [1] "logical"
as.numeric(x)
## [1] 0 1
Algumas vezes não é possível fazer a coerção, então:
x <- c("a", "b", "c")
as.numeric(x)
## Warning: NAs introduced by coercion
## [1] NA NA NA
as.logical(x)
## [1] NA NA NA
Valores perdidos devem ser definidos como NA
(not available):
perd <- c(3, 5, NA, 2)
perd
## [1] 3 5 NA 2
class(perd)
## [1] "numeric"
Podemos testar a presença de NA
s com a função is.na()
:
is.na(perd)
## [1] FALSE FALSE TRUE FALSE
Ou:
any(is.na(perd))
## [1] TRUE
Outros valores especiais são:
NaN
(not a number) - exemplo: 0/0
-Inf
e Inf
- exemplo: 1/0
A função is.na()
também testa a presença de NaN
s:
perd <- c(-1,0,1)/0
perd
## [1] -Inf NaN Inf
is.na(perd)
## [1] FALSE TRUE FALSE
A função is.infinite()
testa se há valores infinitos
is.infinite(perd)
## [1] TRUE FALSE TRUE
Características:
Utilizando a função matrix()
:
matriz <- matrix(1:12, nrow = 3, ncol = 4)
matriz
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
class(matriz)
## [1] "matrix"
Alterando a ordem de preenchimento da matriz (por linhas):
matriz <- matrix(1:12, nrow = 3, ncol = 4, byrow = TRUE)
matriz
## [,1] [,2] [,3] [,4]
## [1,] 1 2 3 4
## [2,] 5 6 7 8
## [3,] 9 10 11 12
Para verificar a dimensão da matriz:
dim(matriz)
## [1] 3 4
Adicionando colunas com cbind()
cbind(matriz, rep(99, 3))
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 2 3 4 99
## [2,] 5 6 7 8 99
## [3,] 9 10 11 12 99
Adicionando linhas com rbind()
rbind(matriz, rep(99, 4))
## [,1] [,2] [,3] [,4]
## [1,] 1 2 3 4
## [2,] 5 6 7 8
## [3,] 9 10 11 12
## [4,] 99 99 99 99
Matrizes também podem ser criadas a partir de vetores adicionando um atributo de dimensão
m <- 1:10
m
## [1] 1 2 3 4 5 6 7 8 9 10
class(m)
## [1] "integer"
dim(m)
## NULL
dim(m) <- c(2, 5)
m
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 3 5 7 9
## [2,] 2 4 6 8 10
class(m)
## [1] "matrix"
Matriz multiplicada por um escalar
matriz * 2
## [,1] [,2] [,3] [,4]
## [1,] 2 4 6 8
## [2,] 10 12 14 16
## [3,] 18 20 22 24
Multiplicação de matrizes (observe as dimensões!)
matriz2 <- matrix(1, nrow = 4, ncol = 3)
matriz %*% matriz2
## [,1] [,2] [,3]
## [1,] 10 10 10
## [2,] 26 26 26
## [3,] 42 42 42
Características:
Utilizando a função list()
:
lista <- list(a = 1:10, b = c("T1", "T2", "T3", "T4"), TRUE, 2 + 2)
lista
## $a
## [1] 1 2 3 4 5 6 7 8 9 10
##
## $b
## [1] "T1" "T2" "T3" "T4"
##
## [[3]]
## [1] TRUE
##
## [[4]]
## [1] 4
class(lista)
## [1] "list"
dim(lista)
## NULL
length(lista)
## [1] 4
Formando uma lista com objetos criados anteriormente:
lista <- list(fator = fator, matriz = matriz)
lista
## $fator
## [1] alta baixa baixa media alta media baixa media media
## Levels: alta media baixa
##
## $matriz
## [,1] [,2] [,3] [,4]
## [1,] 1 2 3 4
## [2,] 5 6 7 8
## [3,] 9 10 11 12
length(lista)
## [1] 2
Características:
Utilizando a função data.frame()
:
da <- data.frame(ano = 2000:2004,
prod = c(32, 54, 25, 48, 29))
da
## ano prod
## 1 2000 32
## 2 2001 54
## 3 2002 25
## 4 2003 48
## 5 2004 29
class(da)
## [1] "data.frame"
dim(da)
## [1] 5 2
Data frames podem ser formados com objetos criados anteriormente, desde que tenham o mesmo comprimento!
length(num)
## [1] 6
length(fator)
## [1] 9
da <- data.frame(numerico = c(num, NA, NA, NA),
fator = fator)
da
## numerico fator
## 1 10 alta
## 2 5 baixa
## 3 2 baixa
## 4 4 media
## 5 8 alta
## 6 9 media
## 7 NA baixa
## 8 NA media
## 9 NA media
class(da)
## [1] "data.frame"
dim(da)
## [1] 9 2
## Estrutura dos dados
str(da)
## 'data.frame': 9 obs. of 2 variables:
## $ numerico: num 10 5 2 4 8 9 NA NA NA
## $ fator : Factor w/ 3 levels "alta","media",..: 1 3 3 2 1 2 3 2 2
A função
str()
é uma das que você precisa decorar!
Para converter um data frame para uma matriz
as.matrix(da)
## numerico fator
## [1,] "10" "alta"
## [2,] " 5" "baixa"
## [3,] " 2" "baixa"
## [4,] " 4" "media"
## [5,] " 8" "alta"
## [6,] " 9" "media"
## [7,] NA "baixa"
## [8,] NA "media"
## [9,] NA "media"
data.matrix(da)
## numerico fator
## [1,] 10 1
## [2,] 5 3
## [3,] 2 3
## [4,] 4 2
## [5,] 8 1
## [6,] 9 2
## [7,] NA 3
## [8,] NA 2
## [9,] NA 2
Geralmente é o resultado de data.matrix()
o qeu você está procurando.
Note que os níveis de um fator são armazenados internamente como números: \(1^\circ\) nível = 1, \(2^\circ\) nível = 2, \(\ldots\)
Objetos do R podem ter nomes, que facilitam a auto-descrição
x <- 1:3
names(x)
## NULL
names(x) <- c("Curitiba", "Paraná", "Brasil")
x
## Curitiba Paraná Brasil
## 1 2 3
names(x)
## [1] "Curitiba" "Paraná" "Brasil"
Listas também podem ter nomes
x <- list(Curitiba = 1, Paraná = 2, Brasil = 3)
x
## $Curitiba
## [1] 1
##
## $Paraná
## [1] 2
##
## $Brasil
## [1] 3
names(x)
## [1] "Curitiba" "Paraná" "Brasil"
Associando nomes às linhas e colunas de uma matriz:
rownames(matriz) <- c("A","B","C")
colnames(matriz) <- c("T1","T2","T3","T4")
matriz
## T1 T2 T3 T4
## A 1 2 3 4
## B 5 6 7 8
## C 9 10 11 12
Para data frames existe uma função especial para os nomes de linhas, row.names()
. Data frames também não possuem nomes de colunas, apenas nomes, já que é um caso particular de lista. Então para verificar/alterar nomes de colunas de um data frame também use names()
.
names(da)
## [1] "numerico" "fator"
row.names(da)
## [1] "1" "2" "3" "4" "5" "6" "7" "8" "9"
Um resumo das funções para alterar/acessar nomes de linhas e colunas em matrizes e data frames.
Classe | Nomes de colunas | Nomes de linhas |
---|---|---|
data.frame |
names() |
row.names() |
matrix |
colnames() |
rownames() |
A
, B
, e C
, repetidas 2, 5, e 4 vezes respectivamente; (2) a matriz do exemplo anterior.fator
, e que seja um vetor da classe fator, idêntico ao objeto caracter
criado acima (que possui apenas os nomes brava
, joaquina
, armação
).Este conteúdo está disponível por meio da Licença Creative Commons 4.0