Universidade Federal do Paraná Prof. Fernando de Pol Mayer
Curso de Graduação em Estatística Lab. de Estatística e Geoinformação - LEG
Departamento de Estatística - UFPR
Funções e objetos. Classes de objetos.
Paulo Justiniano Ribeiro Jr., Fernando de Pol Mayer, Walmes Marques Zeviani
Este obra está licenciado com uma Licença Creative Commons Atribuição-NãoComercial-CompartilhaIgual 4.0 Internacional.
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)
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()
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")
(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
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
Objetos podem armazenar diferentes estruturas de dados:
y <- runif(10)
y
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
≠Dados
≠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
class(num)
Por que numeric
e não integer
?
x <- c(10L, 5L, 2L, 4L, 8L, 9L)
x
class(x)
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)
object.size(x)
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
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")
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
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)
print(x, digits = 7) # padrão
print(x, digits = 22)
Também é possível alterar a representação na tela para o formato científico, usando a função format()
format(x, scientific = TRUE)
Nessa representação, o valor 2.875775e-01 = 2.875775 × 10−01 = 0.2875775.
Usando a função seq()
seq(1, 10)
Ou 1:10
gera o mesmo resultado. Para a sequência variar em 2
seq(from = 1, to = 10, by = 2)
Para obter 15 valores entre 1 e 10
seq(from = 1, to = 10, length.out = 15)
Usando a função rep()
rep(1, 10)
Para gerar um sequência várias vezes
rep(c(1, 2, 3), 5)
Para repetir um número da sequência várias vezes
rep(c(1, 2, 3), each = 5)
Operações podem ser feitas entre um vetor e um número:
num * 2
E também entre vetores de mesmo comprimento ou com comprimentos múltiplos:
num * num
num + c(2, 4, 1)
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)
length(num)
Vetores também podem ter outras classes:
caracter <- c("brava", "joaquina", "armação")
caracter
logico <- caracter == "armação"
logico
logico <- num > 4
logico
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
class(fator)
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
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)
as.numeric(x)
as.logical(x)
as.character(x)
as.factor(x)
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))
class(x)
as.numeric(x)
Algumas vezes não é possível fazer a coerção, então:
x <- c("a", "b", "c")
as.numeric(x)
as.logical(x)
Valores perdidos devem ser definidos como NA
(not available):
perd <- c(3, 5, NA, 2)
perd
class(perd)
Podemos testar a presença de NA
s com a função is.na()
:
is.na(perd)
Ou:
any(is.na(perd))
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
is.na(perd)
A função is.infinite()
testa se há valores infinitos
is.infinite(perd)
Características:
Utilizando a função matrix()
:
matriz <- matrix(1:12, nrow = 3, ncol = 4)
matriz
class(matriz)
Alterando a ordem de preenchimento da matriz (por linhas):
matriz <- matrix(1:12, nrow = 3, ncol = 4, byrow = TRUE)
matriz
Para verificar a dimensão da matriz:
dim(matriz)
Adicionando colunas com cbind()
cbind(matriz, rep(99, 3))
Adicionando linhas com rbind()
rbind(matriz, rep(99, 4))
Matrizes também podem ser criadas a partir de vetores adicionando um atributo de dimensão
m <- 1:10
m
class(m)
dim(m)
dim(m) <- c(2, 5)
m
class(m)
Matriz multiplicada por um escalar
matriz * 2
Multiplicação de matrizes (observe as dimensões!)
matriz2 <- matrix(1, nrow = 4, ncol = 3)
matriz %*% matriz2
Características:
Utilizando a função list()
:
lista <- list(a = 1:10, b = c("T1", "T2", "T3", "T4"), TRUE, 2 + 2)
lista
class(lista)
dim(lista)
length(lista)
Formando uma lista com objetos criados anteriormente:
lista <- list(fator = fator, matriz = matriz)
lista
length(lista)
Características:
Utilizando a função data.frame()
:
da <- data.frame(ano = 2000:2004,
prod = c(32, 54, 25, 48, 29))
da
class(da)
dim(da)
Data frames podem ser formados com objetos criados anteriormente, desde que tenham o mesmo comprimento!
length(num)
length(fator)
da <- data.frame(numerico = c(num, NA, NA, NA),
fator = fator)
da
class(da)
dim(da)
## Estrutura dos dados
str(da)
A função
str()
é uma das que você precisa decorar!
Para converter um data frame para uma matriz
as.matrix(da)
data.matrix(da)
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∘ nível = 1, 2∘ nível = 2, …
Objetos do R podem ter nomes, que facilitam a auto-descrição
x <- 1:3
names(x)
names(x) <- c("Curitiba", "Paraná", "Brasil")
x
names(x)
Listas também podem ter nomes
x <- list(Curitiba = 1, Paraná = 2, Brasil = 3)
x
names(x)
Associando nomes às linhas e colunas de uma matriz:
rownames(matriz) <- c("A","B","C")
colnames(matriz) <- c("T1","T2","T3","T4")
matriz
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)
row.names(da)
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
).