Introdução a Objetos e à Área de Trabalho


***

Parte do livro Introdução à análise de dados com R. Este trabalho está em andamento.  Volte para ver atualizações

Quer fazer sugestões? Deixe um comentário abaixo ou, se você sabe utilizar o github, acesse aqui. Não copie ou reproduza este material sem autorização.

***

Essa frase não vai fazer muito sentido agora, mas é bom você já começar a tê-la em mente: no R, praticamente tudo o que existe na sua área de trabalho é um “objeto”. E praticamente tudo o que acontece na sua área de trabalho é resultado de uma função.

Nesta seção veremos um pouco sobre o objeto mais básico do R, o vetor, e como gerenciar sua érea de trabalho. Aprenderemos, basicamente, algumas formas de criar e remover um objeto (no caso um vetor), como verificar suas propriedades e alterar seus elementos. Ao final veremos como salvar e carregar sua área de trabalho e/ou objetos específicos.

Criando objetos: assignment operators

Durante o uso do R, você irá criar e guardar objetos com um nome, por exemplo:

x1 <- 10 # atribui o valor 10 à variável x1
x1
## [1] 10

O operador <- é conhecido como “assignment operator” e, no caso acima, atribuiu o valor 10 a um objeto de nome x1 (no caso, um vetor). Na maior parte das vezes, o operador = é equivalente a <-. Vejamos:

x2 = 20 # atribui o valor 20 à variável x2
x2
## [1] 20

Neste livro recomendaremos o uso do <- pois ele funciona sempre como atribuição. O operador = é usado para definir argumentos dentro de um função e, assim, seu comportamento pode ser diferente de uma atribuição em certos casos (veremos isso mais a frente). Contudo, na maior parte das vezes o uso de = e <- é indiferente, então desde que você seja consistente, escolha a forma que mais lhe agradar.

Estudaremos funções mais a fundo em outra seção, mas, é importante desde já ter a idéia de que o assignment operator <- nada mais é do que uma função. Para se chamar uma função utiliza-se seu nome seguido dos argumentos entre parênteses, isto é, funcao(argumento1, argumento2, ...).

Dessa forma, poderíamos ter chamado o operado <- com a sintaxe de uma função (usando os backticks para auxiliar). Isto é, o comando:

`<-`("x1", 10)

É equivalente a

x1 <- 10

Não se preocupe se você não estiver entendendo tudo agora, mais para frente esses detalhes passarão a fazer mais sentido.

Além do =, outra função que é de certo modo equivalente a <- é a função assign(), que toma a forma assign("nomeObjeto", valorObjeto).

# cria a variável x3 com o valor 4
assign("x3", 4)
x3
## [1] 4
# veja que é equivalente a x3 <- 4
x3 <- 4
x3
## [1] 4

Uma vez que você atribuiu uma variável a um nome, você pode utilizá-la em operações e funções utilizando seu nome.

x1 + x2 + x3 # soma x1,x2,x3
## [1] 34
x1/x2 # divide x1 por x2
## [1] 0.5
x1 * x2 # multiplica x1 por x2
## [1] 200

E você pode guardar os resultados dessas operações em outras variáveis:

y <- x1*x2 + x3 #cria y com o resultado de x1*x2 + x3
y
## [1] 204

Nomes de variáveis

O R é case sensitive – isto é, letras maiúsculas e minúsculas são diferenciadas – portanto x1 (com x minúsculo) e X1 (com x maiúsculo) são objetos diferentes.

X1 # O R não vai encontrar, pois não criamos X1 com X maiúsculo.
## Error in eval(expr, envir, enclos): objeto 'X1' não encontrado
x1 # Encontra normalmente
## [1] 10

Os nomes dos objetos no R podem conter combinações arbitrárias de números, textos, bem como ponto ( . ) e underscore ( _ ). Entretanto, os nomes não podem começar com números ou underscore.

a1_B2.c15 <- "variável com nome estranho"
a1_B2.c15
## [1] "variável com nome estranho"
_x <- 1 # erro, pois começa com underscore
1var <- 1 # erro, pois começa com número

Existem alguns caracteres reservados que também não podem ser utilizados no início dos nomes (como operadores matemáricos +, -,), mas o R é bastante flexível, e todas essas regras podem ser “burladas” se você utilizar backticks ( ).

`_x` <- 1 # agora funciona
`+variavel` <- 100 # funciona
`1var` <- 1 #  funciona

Concatenando valores

Até agora construimos vetores com apenas um elemento. Uma das formas de construir um vetor com mais elementos é concatenando uma quantidade arbitrária de objetos com a função c().

x3 <- c(x1, 2, 3, x2) # concatena x1, 2, 3 e x2.
x3
## [1] 10  2  3 20
x4 <- c("a", "b","c") # concatena "a", "b" e "c"
x4
## [1] "a" "b" "c"

Classes de vetores

No R, a estrutura mais simples de dados é um vetor. Os vetores no R podem ser, entre outros, de classes: numeric (números de ponto flutuante), integer (número inteiro), complex (número complexo), character (texto), logical (lógicos, booleanos). Há também datas e fatores, que discutiremos mais a frente. Os objetos x1 e x2, por exemplo, são vetores numéricos de tamanho 1

Criemos alguns vetores para cada uma dessas classes:

numero <- c(546.90, 10, 789)

# note o L
inteiro <- c(1L, 98L) 

# note o i
complexo <- c(20i, 2+9i) 

# notem as aspas
texto <- c("Um texto de exemplo", "outro texto", "mais texto")

# sempre maiúsculo
logico <- c(TRUE, FALSE, TRUE)

Note que inteiros são criados seguidos de um L maiúsculo. Números complexos são seguidos de um i minúsculo. Textos podem ser criados com aspas duplas ("texto") ou simples ('texto'). Vetores lógicos são criados pelas palavras TRUE ou FALSE, sempre em maiúsculo (e podem ser abreviados para T ou F, mas não recomendamos).

A função class() é útil para identificar a classe de um determinado objeto. Verifiquemos as classes dos objetos que acabamos de criar:

class(numero)
## [1] "numeric"
class(inteiro)
## [1] "integer"
class(complexo)
## [1] "complex"
class(texto)
## [1] "character"
class(logico)
## [1] "logical"

Você pode testar se um vetor é de determinada classe com as funções is.xxx (sendo “xxx” a classe). Por exemplo:

is.numeric(numero)
## [1] TRUE
is.character(numero)
## [1] FALSE
is.character(texto)
## [1] TRUE
is.logical(texto)
## [1] FALSE

E você também pode forçar a conversão de um vetor de uma classe para outra com as funções as.xxx (sendo “xxx” a classe). Entretanto, nem sempre essa conversão faz sentido, e pode resultar em erros ou NA’s (veremos NA’s mais a frente). Por exemplo:

as.character(numero) # Vira texto
## [1] "546.9" "10"    "789"
as.numeric(logico) # TRUE -> 1, FALSE -> 0
## [1] 1 0 1
as.numeric(texto) # Não faz sentido
## Warning: NAs introduzidos por coerção
## [1] NA NA NA
as.numeric("1012312") # Faz sentido
## [1] 1012312

Estrutura e tamanho de um objeto

Para ver a estrutura de um objeto, use a função str(). Esta é uma função simples, mas talvez uma das mais úteis do R.

Vejamos um exemplo simples, a estrutura do objeto x3

str(x3)
##  num [1:4] 10 2 3 20

Note que o resultado de str() fornece várias informações: trata-se de um vetor numérico (num), com 4 elementos ([1:4]) e os primeiros elementos do vetor são (10 2 3 20).

Se você estiver utilizando o RStudio, um resumo dessa mesma informação já estará aparcendo no seu canto superior direito.

rstudio_str

Teste o resultado de str() em alguns dos outros objetos que criamos e repare nos resultados:

str(x1)
##  num 10
str(x4)
##  chr [1:3] "a" "b" "c"
str(numero)
##  num [1:3] 547 10 789
str(inteiro)
##  int [1:2] 1 98
str(complexo)
##  cplx [1:2] 0+20i 2+9i
str(texto)
##  chr [1:3] "Um texto de exemplo" "outro texto" "mais texto"
str(logico)
##  logi [1:3] TRUE FALSE TRUE

Para obter o tamanho de um objeto, utilize a função length(). Note que comandos no R podem ser colocados na mesma linha se separados por ponto-e-vírgula (;).

length(x1)
## [1] 1
length(x3)
## [1] 4
length(x4)
## [1] 3
length(numero); length(inteiro)
## [1] 3
## [1] 2

Elementos de um vetor

Você pode acessar elementos de um vetor por meio de colchetes [ ] e sua posição.

numero[1] # apenas primeiro elemento do vetor número
## [1] 546.9
numero[c(1,2)] # elementos 1 e 2
## [1] 546.9  10.0
numero[c(1,3)] # elementos 1 e 3
## [1] 546.9 789.0
numero[c(3,1,2)] # troca de posição
## [1] 789.0 546.9  10.0

Índices negativos podem ser utilizados para selecionar todos os demais elementos de um vetor, exceto aquele que está no índice. Por exemplo:

# seleciona todos os elementos menos o primeiro
numero[-1]
## [1]  10 789
numero[-c(1,2)] # todos menos 1 e 2
## [1] 789
numero[-c(1,3)] # todos menos 1 e 3
## [1] 10
numero[-3] # todos menos 3
## [1] 546.9  10.0

Nomes dos elementos

Objetos podem ter seus elementos nomeados. A função names() nos dá os nomes desses elementos:

names(numero)
## NULL

Note que o resultado foi NULL pois os elementos do vetor numero ainda não foram nomeados. Façamos isso, portanto, utilizando a função names()<-

numero
## [1] 546.9  10.0 789.0
names(numero) <- c("numero1", "numero2", "numero3")
numero
## numero1 numero2 numero3
##   546.9    10.0   789.0

Agora, além de acessar o elemento do vetor pela posição, pode-se utilizar seu nome.

# seleciona o elemento de nome "numero1"
numero["numero1"]
## numero1
##   546.9
# seleciona o elemento de nome "numero2"
numero["numero2"]
## numero2
##      10
# seleciona o elemento de nome "numero3"
numero["numero3"]
## numero3
##     789
# seleciona os elementos de nome "numero1" e "numero3"
numero[c("numero1", "numero3")]
## numero1 numero3
##   546.9   789.0

Alterando elementos

Com o assignment operator e o colchetes, consegue-se alterar apeans alguns elementos específicos de um vetor.

Você pode fazer isso utilizando índices numéricos:

numero
## numero1 numero2 numero3
##   546.9    10.0   789.0
numero[1] <- 100 # altera elemento 1 para 100
numero
## numero1 numero2 numero3
##     100      10     789
numero[2:3] <- c(12.3, -10) # altera elementos 2 e 3
numero
## numero1 numero2 numero3
##   100.0    12.3   -10.0

O que ocorre se você colocar um índice maior do que o tamanho do vetor? O R estende o vetor até o tamanho do índice, e preenche os valores restantes com NA (veremos mais sobre NA a frente):

numero[10] <- 50 # o vetor número não tem 10 elementos...
numero # ao elemento 10 foi atribuido o valor 50 e o restante foi preenchido com NA
## numero1 numero2 numero3
##   100.0    12.3   -10.0      NA      NA      NA      NA      NA      NA
##
##    50.0

Como deletar um elemento de um vetor? Basta usar o índice negativo e sobrescrever o resultado:

logico # 3 elementos
## [1]  TRUE FALSE  TRUE
logico <- logico[-2] # deletamos o segundo elemento
logico
## [1] TRUE TRUE

Você também pode modificar o vetor utilizando os nomes dos elementos:

numero["numero3"] <- 431
numero
## numero1 numero2 numero3
##   100.0    12.3   431.0      NA      NA      NA      NA      NA      NA
##
##    50.0
numero[c("numero1", "numero2")] <- c(-100, 100)
numero
## numero1 numero2 numero3
##    -100     100     431      NA      NA      NA      NA      NA      NA
##
##      50

Ordenando um vetor

A função order() retorna um vetor com as posições para que um objeto fique em ordem crescente.

order(numero) # indices
##  [1]  1 10  2  3  4  5  6  7  8  9
numero[order(numero)] # ordena numero
## numero1         numero2 numero3
##    -100      50     100     431      NA      NA      NA      NA      NA
##
##      NA

A função sort() retorna o vetor ordenado.

sort(numero)
## numero1         numero2 numero3
##    -100      50     100     431

As duas funções tem o parâmetro decreasing que, quando TRUE, retornam o vetor de em ordem decrescente.

Encontrando e removendo objetos

Para listar todos os objetos que estão na sua área de trabalho, você pode usar a função ls() ou objects().

ls()
##  [1] "_x"        "+variavel" "1var"      "a1_B2.c15" "complexo"
##  [6] "inteiro"   "logico"    "numero"    "texto"     "x1"
## [11] "x2"        "x3"        "x4"        "y"
objects()
##  [1] "_x"        "+variavel" "1var"      "a1_B2.c15" "complexo"
##  [6] "inteiro"   "logico"    "numero"    "texto"     "x1"
## [11] "x2"        "x3"        "x4"        "y"

Note que apareceram todos os objetos que criamos.

A função rm(objeto) remove um objeto da área de trabalho.

rm(x3) # remove o objeto x3 da área de trabalho
x3 # não encontrará o objeto
## Error in eval(expr, envir, enclos): objeto 'x3' não encontrado
ls() # note que x3 não aparecerá na lista de objetos
##  [1] "_x"        "+variavel" "1var"      "a1_B2.c15" "complexo"
##  [6] "inteiro"   "logico"    "numero"    "texto"     "x1"
## [11] "x2"        "x4"        "y"

Voltando à função ls(), note que o que ela retorna também é um objeto: é um vetor de tipo “texto”, ou, como vimos, na terminologia do R, do tipo “character”. Este resultado pode ser atribuído a um objeto e armazenado na área de trabalho.

lista_obj <- ls() # guarda o resultado de ls() na variável lista_obj
lista_obj
##  [1] "_x"        "+variavel" "1var"      "a1_B2.c15" "complexo"
##  [6] "inteiro"   "logico"    "numero"    "texto"     "x1"
## [11] "x2"        "x4"        "y"
ls()
##  [1] "_x"        "+variavel" "1var"      "a1_B2.c15" "complexo"
##  [6] "inteiro"   "lista_obj" "logico"    "numero"    "texto"
## [11] "x1"        "x2"        "x4"        "y"

Isto pode ser interessante pois a função rm() aceita um parâmetro de texto (list) para remover objetos. Por exemplo:

rm(list=lista_obj) # remove todos os objetos que estão na lista_obj
ls() # note que sobrou apenas lista_obj
## [1] "lista_obj"

Desta forma, um atalho para remover todos os objetos da sua área de trabalho é rm(list = ls()).

A função ls() também aceita um parâmetro (pattern) que define um padrão na busca dos objetos no ambiente de trabalho. O pattern é bem flexível e inclusive aceita expressões regulares (veremos expressões regulares mais a frente). Por exemplo, o comando ls(pattern="y") irá buscar todas as variáveis que contenham “y” no seu nome.

Buscando apenas as variáveis que contenham “y” no nome:

x1 <- 1:10 #  x1 números de 1 a 10
x2 <- c(2, 4,9); y1 <- 50; y2 <- 10 # ; comandos na mesma linha
ls() # lista tudo
## [1] "lista_obj" "x1"        "x2"        "y1"        "y2"
ls(pattern="y") # lista somente y1 e y2
## [1] "y1" "y2"

Combinando este recurso do ls() com o rm() você pode remover apenas certos objetos.

rm(list=ls(pattern="y")) #remove todos os objetos que contenham "y".
ls()
## [1] "lista_obj" "x1"        "x2"

Salvando e carregando objetos

Para salvar uma cópia da sua área de trabalho você pode utilizar a função save.image():

# salva a área de trabalho no arquivo "aula_1.RData"
save.image(file="aula_1.RData")

Agora você pode recuperar todos os objetos com load().

# vamos remover todos os objetos da área de trabalho
rm(list=ls())
ls() # não encontra nada
## character(0)
load(file="aula_1.RData")
ls() # note que os objetos foram carregados
##  [1] "dados_2010_11_10" "dados_2013_11_10" "encoding"
##  [4] "input"            "novembro"         "out"
##  [7] "outubro"          "publish"          "shortcode"
## [10] "title"

Com a função save() é possível salvar apenas um ou um conjunto de objetos.

# simula 100 obs de uma normal(10, 2)
sim_normal <- rnorm(100, mean=10, sd=2)

# salva no arquivo sim_normal.RData e remove da área de trabalho
save(sim_normal, file="sim_normal.RData")
rm(sim_normal)
ls() # sim_normal não aparece
##  [1] "dados_2010_11_10" "dados_2013_11_10" "encoding"
##  [4] "input"            "novembro"         "out"
##  [7] "outubro"          "publish"          "shortcode"
## [10] "title"
# carrega sim_normal.RData
load(file="sim_normal.RData")
ls() # sim_normal aparece
##  [1] "dados_2010_11_10" "dados_2013_11_10" "encoding"
##  [4] "input"            "novembro"         "out"
##  [7] "outubro"          "publish"          "shortcode"
## [10] "sim_normal"       "title"

Estas operações podem ser realizadas com o botão de salvar no canto direito do RStudio.

Outro conjunto de funções para salvar e ler objetos do R são saveRDS() e readRDS(). Uma das principais diferenças com relação a save() e load() é que, enquanto estas salvam e carregam os objetos com o seu nome original, as funções RDS permitem a você carregar o objeto com um nome diferente.

saveRDS(sim_normal, file="sim_normal.rds")
rm(sim_normal)
### carrega sim_normal.rds em um objeto com nome diferente ###
simulacao <- readRDS("sim_normal.rds")
ls()
##  [1] "dados_2010_11_10" "dados_2013_11_10" "encoding"
##  [4] "input"            "novembro"         "out"
##  [7] "outubro"          "publish"          "shortcode"
## [10] "simulacao"        "title"

Exercícios

Agora é sua vez.

  • Remova todos os objetos do ambiente de trabalho.
  • Crie objetos com nomes dados_2010_10_10, dados_2010_11_10, dados_2013_10_10, dados_2013_11_10. Faça com que os objetos sejam do tipo numérico, character, lógico e inteiro. Verifique a classe e a estrutura dos objetos criados.
  • Use ls() para listar apenas os dados de Novembro. E depois para listar apenas os dados de Outubro. Use rm() para remover apenas os dados de outubro (dica: você vai precisar do resultado de ls()).
  • Salve sua area de trabalho com o nome exercicio_objetos.RData. Salve apenas dados_2010_11_10 com o nome dados_2010_11_10.RData.

Soluções

rm(list=ls()) # remove todos os objetos

dados_2010_10_10 <- 10.5
dados_2010_11_10 <- "texto"
dados_2013_10_10 <- TRUE
dados_2013_11_10 <- 24L

class(dados_2010_10_10)
class(dados_2010_11_10)
class(dados_2013_10_10)
class(dados_2013_11_10)

str(dados_2010_10_10)
str(dados_2010_11_10)
str(dados_2013_10_10)
str(dados_2013_11_10)

novembro <- ls(pattern="_11_")
outubro <- ls(pattern="_10_")

rm(list=outubro)

save.image(file="exercicios_objetos.RData")
save(dados_2010_11_10, file="dados_2010_11_10.RData")

Fluxo de caixa descontado, O melhor jogo de tabuleiro do planeta, teoria dos jogos e casamentos.


Alguns links interessantes pós-carnaval. Hora de voltar ao ritmo.

– Damodaran fez um post bem bacana sobre fluxo de caixa descontado (FCD), mostrando que não é somente, digamos, um fluxo de caixa descontado. Vale a pena pela etimologia de FCDs mal-feitos e pelo checklist para saber se você está fazendo direito.

– Como fazer o melhor jogo de tabuleiro do planeta? War, Jogo da Vida e Banco Imobiliário estão entre os piores? Dois posts bacanas do 538 que queria ter compartilhado há algum tempo seguem agora aqui e aqui.

– Dollar auction na vida real, por  SMBC:

20141229

A Petrobras está barata?


Em seu último post, Damodaran resolveu falar da Petrobras. Sobre a gestão recente da companhia, sua opinião pode ser resumida na seguinte frase:

Put in brutally direct terms, if you were given a valuable business and given the perverse objective of destroying it completely and quickly, you should replicate what Petrobras has done (…)

Damoradan fez também um valuation bem simples. Nas combinações abaixo, são poucos os cenários em que o valor da empresa fica acima do atual valor de mercado – mas ainda restam alguns aos esperançosos.

Note que os valores estão em dólar (ou seja, o valor atual da petro estaria em torno de $3,00 a $3,30 dólares).

PBRpricematrix

E se você quiser brincar com outras hipóteses, baixe a planilha em Excel aqui.

 

Economia comportamental


Flávia Ávila me avisou do site Economia Comportamental, que busca difundir a área no Brasil, e reune informações sobre cursosvídeos, grupos de pesquisa entre outras coisas interessantes.  A página também tem um blog e já conta com diversos colaboradores.

A iniciativa é louvável, pois esta é uma área de pesquisa que ainda está carente de divulgação e publicações no país.  Àqueles que publicam sobre o tema por aqui, sugiro entrar em contato com a Flávia para divulgar o trabalho. E para quem tem interesse no tema, vale a pena fazer uma visita!