Introdução ao R - Módulo II

Autor: Pablo Fonseca

04 de Junho de 2018

Tipos, criação e manipulação de objetos

O R pode ser considerado como uma grande e complexa calculadora, onde diferentes cálculos e funções podem ser executadas. A diferença básica, mas fundamental do R, é a forma com que os resultados são armazenados. O R utiliza a programação orientada a objetos (POO). Dentre outras características, a POO utiliza um objeto que é capaz de armazenar informações e reagir a mensagens enviadas a ele, se relacionar e enviar mensagens a outros objetos. A utilização de objetos é uma das grandes funcionalidades do R e permite a aplicação de diversas ações.

Os objetos são as unidades básicas que serão utilizadas para construir funções e rotinas mais complexas. Os objetos podem ser comparados aos tijolos que irão construir um muro, que futuramente irão constituir uma casa. Os tijolos devem ser construidos seguindo específicações e posicionados de uma maneira lógica para a construção do muro. Da mesma forma, os objetos no R devem ser construídos baseados em constituições epecíficas, chamadas de classes. Além disso, os objetos devem ser ordenados e utilizados de maneira lógica dentro dos algoritmos. Assim como no caso dos tijolos, que possuem diferentes tipos para diversas funcionalidades, os objetos do R também possuem diferentes tipos. A seguir, iremos aprender como criar e manipular objetos no R. Além disso, iremos aprender sobre os diferentes tipos de objetos no R, assim como as classes das variáveis inseridas nos objetos.

Os objetos podem receber qualquer nome. Contudo, é interessante seguir algumas normas para facilitar a identificação do objeto e evitar problemas no manuseio ao longo da criação dos códigos. O nome dos objetos não pode conter espaços, assim, caso você queira diferenciar duas palavras, utilize os símbolos “-” ou “_“. Além disso, evite utilizar nomes muito compridos ou muito curtos para descrever objetos. Não utilize caracteres especiais no momentode nomear objetos. A presença de letras maiúsculas ou minúsculas diferentes no nome dos objetos é o suficiente criar dois nomes distintos. Por exemplo, o objeto objeto1 não será o mesmo objeto que o objeto1. Os objetos são a unidade básica de todas ações que executamos no R. Portanto, devemos criá-los com bastante cuidado.

Criando objetos no R

As informações podem ser inseridas em objetos no R de duas maneiras:

  1. Utilizando o símbolo de “=”
objeto1=1
  1. Utilizando o símbolo “<-”
objeto2<-1

Ambas as formas irão resultar na criação de um objeto contendo o mesmo valor, no caso, o número 1.

objeto1
## [1] 1
objeto2
## [1] 1

As duas formas de inserir informações em um objetos do R funcionam da mesma forma. Contudo, a utilização do símbolo “<-” infere uma ideia de direção no momento de inserir o conteúdo. Por exemplo:

objeto3<-1

objeto4<-objeto3

objeto4
## [1] 1

Neste caso, criamos o objeto3 onde inserimos o valor 1. Após a criação do objeto 3, o valor presente no mesmo foi inserido no objeto4. Utilizando o símbolo “<-” conseguimos demonstrar que o valor do objeto3 foi inserido no objeto4 e não vice-versa. No caso da utilização do símbolo “=”, essa ideia de direção não seria possível. Além disso, a questão da direção pode ser diretamente aplicada com a utilização do símblo “<-”. Por exemplo:

objeto1<-1

objeto2<-2

objeto1
## [1] 1
objeto2
## [1] 2
objeto1<-objeto2

objeto1
## [1] 2

Nos comandos acima, criamos o objeto1 e o objeto2. Após a criação de ambos, o valor do objeto2 foi inserido no objeto1. Simplesmente invertendo a ordem do simbolo “<-” para “->”, o valor do objeto1 será inserido no objeto2.

objeto1<-1

objeto2<-2

objeto1
## [1] 1
objeto2
## [1] 2
objeto2->objeto1

objeto2
## [1] 2

OBS: Apesar dessa possibilidade, é interessante padronizar a posição do objeto que receberá a informação e do objeto ou valor que irá “ceder” a informação. Geralmente, o objeto a ser criado fica à esquerda daquele que irá “ceder” a informação.



Além de alocar e transferir valores entre objetos, é possível realizar operações entre objetos. Vamos criar duas variáveis “numeroA”" e “numeroB”, com os valores 2 e 4, respectivamente.

numeroA<-2

numeroB<-4

numeroA
## [1] 2
numeroB
## [1] 4

Utilizando os objetos criados, vamos aplicar algumas operações básicas entre eles.

  1. Soma
resultadoSoma<-numeroA+numeroB

resultadoSoma
## [1] 6

O símbolo utilizado para informar que a operação de soma ocorre é “+”.

  1. Subtração
resultadoSubtracao<-numeroA-numeroB

resultadoSubtracao
## [1] -2

O símbolo utilizado para informar que a operação de subtração ocorre é “-”.

  1. Multiplicação
resultadoMultiplicacao<-numeroA*numeroB

resultadoMultiplicacao
## [1] 8

O símbolo utilizado para informar que a operação de multiplicação ocorre é “*“.

  1. Divisão
resultadoDivisao<-numeroA/numeroB

resultadoDivisao
## [1] 0.5

O símbolo utilizado para informar que a operação de divisão ocorre é “/”.

Inserindo múltiplos valores em objetos no R

Os objetos no R possuem a funcionalidade de receberem múltiplos valores e armazená-los de diferentes formas. Abaixo, iremos ver algumas como inserir múltiplos valores em um objeto simples. Em seguida, iremos observar como as operações entre objetos com múltiplos valores irão se comportar. Por fim, iremos aprender como recuperar valores em posições específicas desse objeto.

Entender como os objetos são manipulados e reagem a operações é dos principais pontos para o aprendizado do R. A lógica relacionada à manipulação de objetos simples podem ser extrapolada para outros tipos de objetos. Portanto, todos esses passos serão muito importantes para todo o restante das atividades envolvendo o R.

A principal forma de inserir uma combinação de números em um objeto no R é pela utilização da função “c()”. Essa função é chamada de combine e tem como objetivo combinar vários elementos em um objeto.

O objeto que contém vários elementos é denominado VETOR.

vetorA<-c(1,2,3,4,5)

vetorA
## [1] 1 2 3 4 5

O output apresentado acima mostra o conteúdo presente do vetor vetorA. Nele é possível notar que os valores inseridos no vetor estão organizados da mesma forma que foram informados.

Assim como números, outros tipos de valores podem ser inseridos em vetores, como por exemplo, nomes, letras ou combinações alfa-númericas.

vetorB<-c("Fernanda","Laura", "João", "Pedro", "Pablo")

vetorB
## [1] "Fernanda" "Laura"    "João"     "Pedro"    "Pablo"

OBS: A diferenciação entre caracteres e objetos no R é feita através da presença de aspas duplas ou simples (“” ou ’’) antes e após o conjunto de caracteres. Por exemplo, caso no exemplo acima a palavra “Fernanda” fosse informada sem as aspas, o R tentaria encontrar um objeto de nome Fernanda e uma mensagem de erro seria informada, pois nenhum objeto com o nome de Fernanda foi criado.

vetorB<-c("Fernanda","Laura", João, "Pedro", "Pablo")
## Error in eval(expr, envir, enclos): objeto 'João' não encontrado

Futuramente iremos discutir a possibilidade de incluir vários objetos ou vetores em outro vetor utilizando o comando “c()”.


Operações básicas utilizando vetores

As operações envolvendo vetores no R utilizam os mesmos caracteres para a sua execução. Contudo, o que diferencia é a forma com que o output é gerado. Iremos criar dois vetores vetorA e vetorB, preenchidos com c(1,2,3,4,5) e c(10,20,30,40,50), respectivamente, para exemplificarmos o comportamento das operações envolvendo vetores.

vetorA<-c(1,2,3,4,5)

vetorB<-c(10,20,30,40,50)

vetorA
## [1] 1 2 3 4 5
vetorB
## [1] 10 20 30 40 50

Inicialmente iremos utilizar somente o vetorA e todas as operações serão realizadas utilizando o valor 10.

  1. Soma
resultadoSoma<-vetorA+10

resultadoSoma
## [1] 11 12 13 14 15
  1. Subtração
resultadoSubtracao<-vetorA-10

resultadoSubtracao
## [1] -9 -8 -7 -6 -5
  1. Multiplicação
resultadoMultiplicacao<-vetorA*10

resultadoMultiplicacao
## [1] 10 20 30 40 50
  1. Divisão
resultadoDivisao<-vetorA/10

resultadoDivisao
## [1] 0.1 0.2 0.3 0.4 0.5


Note que todos os elementos do vetorA foram alterados pelo resultado da operação correspondente utilizando o número 10 e armazenados no respectivo output. Ou seja, uma operação realizada com um vetor será aplicada a todos os elementos, caso não haja especificação de qual elemento utilizar.


A seguir, veremos como o resultado das operações entre dois vetores se comporta.

  1. Soma
resultadoSoma<-vetorA+vetorB

resultadoSoma
## [1] 11 22 33 44 55
  1. Subtração
resultadoSubtracao<-vetorA-vetorB

resultadoSubtracao
## [1]  -9 -18 -27 -36 -45
  1. Multiplicação
resultadoMultiplicacao<-vetorA*vetorB

resultadoMultiplicacao
## [1]  10  40  90 160 250
  1. Divisão
resultadoDivisao<-vetorA/vetorB

resultadoDivisao
## [1] 0.1 0.1 0.1 0.1 0.1


Todos os resultados acima apresentam o mesmo padrão. Perceba que o resultado da operação aplicada em cada vetor é resultado da interação entre o primeiro elemento do vetorA com o primeiro elemento do vetorB, do segundo elemento do vetorA com o segundo elemento do vetorB e assim subsequentemente até o término dos vetores.

Essa é uma característica importante, uma vez que vetores de tamanhos diferentes quando envolvidos em processos de interação (como as operações descritas acima), seguem um padrão semelhante.

vetorC<-c(1,2,3)

vetorD<-c(10,20)

resultado<-vetorC+vetorD
## Warning in vetorC + vetorD: comprimento do objeto maior não é múltiplo do
## comprimento do objeto menor
resultado
## [1] 11 22 13

No exemplo acima, é possível notar que o primeiro elemento do vetorC é somado ao primeiro elemento do vetorD e o segundo elemento do vetorC é somado ao segundo elemento do vetorD. Contudo, o vetorC possui três elementos, com isso, esse terceiro elemento é somado ao primeiro elemento do vetorC. Esse padrão de interação entre os vetores é muito importante de ser entendido. Iremos trabalhar esse conceito diversas vezes ao longo do curso.


Outras formas de criar vetores

Abaixo serão listadas algumas formas de se criar objetos no R. É interessante ressaltar que no R, existem várias formas de se fazer a mesma coisa. Portanto, caso vocês encontrem alternativas para os comandos abaixos e cheguem no mesmo resultado, não necessariamente estarão errados.

  1. Integrando vários vetores em um novo vetor

Esse processo pode ser simplesmente executado por meio da utilização do comando “c()”, usando como argumentos (as informações contidas dentro dos parênteses) os demais vetores.

vetorA<-c(1,2,3)
  
vetorB<-c(5,6,7)
  
vetorC<-c(2,2,2)  

combVetor<-c(vetorA, vetorB, vetorC)  

combVetor
## [1] 1 2 3 5 6 7 2 2 2
  1. Criando sequências númericas

O R possui algumas funções básicas para criação de sequências e conjunto de caracteres repetidos que podem ser muito úteis durante a criação de rotinas.

2.a) Criando sequências numéricas

A função “seq()” é utilizada para a criação de sequencias númericas seguindo diferentes padrões determinados. Dentro dos parênteses os argumentos requeridos para a função são: from=, to= e by=. Portanto, para criar uma sequência numérica partindo de 1 até 10, incrementando os valores de 1 em 1, o código referente ficaria da seguinte forma.

seqA<-seq(from=1,to=10,by=1)

seqA
##  [1]  1  2  3  4  5  6  7  8  9 10

Note que os argumentos dentro da função “seq()” são separados por vírgulas. Isso é uma característica muito importante que deve ser mantida e utilizada em todas as funções no R. Além disso, uma outra característica interessante é o fato de que os nomes dos argumentos podem ser omitidos, desde que a ordem pré-estabelecida no manual da função seja respeitada. Por exemplo, o comando abaixo irá resultar no mesmo output apresentado logo acima.

seqA<-seq(1,10,1)

seqA
##  [1]  1  2  3  4  5  6  7  8  9 10

Contudo, caso alteremos as posições entre o primeiro e o segundo argumento da função, uma mensagem de erro será informada. Uma vez que não é possível criar uma sequência númerica que inicie por um número maior do que o número final. Isso é possível se decrementarmos o número ao invés de incrementar. Mais abaixo apresentaremos como realizar essa ação.

seqA<-seq(10,1,-1)

seqA
##  [1] 10  9  8  7  6  5  4  3  2  1

A mensagem de erro “Error in seq.default(10, 1, 1): wrong sign in ‘by’ argument” mostra exatamente o fato de que necessitaríamos decrementar o número para que a sequência fosse possível de ser criada. Contudo, caso informemos o nome dos argumentos, a ordem em que eles são apresentados na função não fará diferença (na grande maioria das vezes).

seqA<-seq(to=10,by=1,from=1)

seqA
##  [1]  1  2  3  4  5  6  7  8  9 10

Nesse momento, iremos descobrir como criar sequências decrescentes, aplicando o processo de decremento. Por exemplo, vamos criar uma sequência que inicie em 20 e vá até -20 sendo decrementada de 2 em 2.

seqB<-seq(from=20,to=-20,by=-2)

seqB
##  [1]  20  18  16  14  12  10   8   6   4   2   0  -2  -4  -6  -8 -10 -12
## [18] -14 -16 -18 -20

Outra maneira bem simples de criar uma sequência de números no R é a utilização do caracter “:” entre dois números. Por exemplo, vamos criar uma sequencia de 5 até 10 usando essa estratégia.

seqC<-5:10

seqC
## [1]  5  6  7  8  9 10

Contudo, é importante notar que com essa estratégia, os números só podem ser incrementados ou decrementados de 1 em 1.

2.b) Criando sequências de caracteres alfabéticos

Além das sequências numéricas, é possível criar sequências com caracteres alfabéticos por meio das funções “letters()” e “LETTERS()”. A diferença entre as duas funções encontra-se no seu output. A função “letters()” irá criar uma sequência de caracteres minúsculos, enquanto a função “LETTERS()” uma sequência de caracteres maiúsculos (de uma maneira bem intuitiva). Essas funções funcionam a partir dos indexes (posições) dos caracteres na sequência alfabética. Por exemplo, vamos criar uma sequência de letras que vá de “a” a “h”.

vetor_letters<-letters[1:8]

vetor_letters
## [1] "a" "b" "c" "d" "e" "f" "g" "h"
vetor_letters<-LETTERS[1:8]

vetor_letters
## [1] "A" "B" "C" "D" "E" "F" "G" "H"

Como vocês puderam notar, não utilizamos “()” para determinar os argumentos de letters e LETTERS. Isso se deve ao fato de que, na verdade essas duas estruturas não serem funções, mas sim vetores. Nesse caso, estamos utilizando uma maneira de recuperar subconjuntos de elementos alocados em vetores pré-existentes no R. Mais à frente iremos discutir bastante as diversas formas de extrair subconjuntos de elementos de diferentes tipos de elementos no R.

2.c) Criando sequências de números ou caracteres repetidos

A função “rep()” pode ser utilizada para criar um vetor com um número pré-determinado de repetições de um determinado elemento. Por exemplo, vamos criar três vetores. O primeiro contendo o número 9 repretido 13 vezes, o segundo contendo a letra “X” repetida 13 vezes e o terceiro contendo o número 2 repetido 13 vezes. Os argumentos obrigatórios a serem informados à função “rep()” são “x” e “times”.

repA<- rep(x=9, times=13)

repA
##  [1] 9 9 9 9 9 9 9 9 9 9 9 9 9
repB<- rep(x="X", times=13)

repB
##  [1] "X" "X" "X" "X" "X" "X" "X" "X" "X" "X" "X" "X" "X"
repC<- rep(x=2, times=13)

repC
##  [1] 2 2 2 2 2 2 2 2 2 2 2 2 2

Além disso, podemos combinar diferentes funções no R. Por exemplo, a função “c()” pode ser combinada com a função “rep()” para gerar um vetor contendo os resutados dos três vetores gerados anteriormente.

combRep<-c(rep(x=9, times=13),rep(x="X", times=13),rep(x=2, times=13))

combRep
##  [1] "9" "9" "9" "9" "9" "9" "9" "9" "9" "9" "9" "9" "9" "X" "X" "X" "X"
## [18] "X" "X" "X" "X" "X" "X" "X" "X" "X" "2" "2" "2" "2" "2" "2" "2" "2"
## [35] "2" "2" "2" "2" "2"

2.d) Criando vetores de números aleatórios

Existem duas funções muito utilizadas para a criação de sequências (ou sorteio de apenas um número) de números aleatórios no R. Essas função são: “runif()” e “sample()”.

A função “runif()” possui três argumentos obrigatórios: n, min e max. Esses argumentos representam o número de elementos a serem gerados, o valor mínimo possível de ser sorteado e o valor máximo possível, respectivamente.

É interessante ressaltar que a função “runif()” pode selecionar de maneira aleatória qualquer número contido no conjunto dos números racionais. Ou seja, quaquer número inteiro ou fracionário, positivo ou negativo, contido no intervalo informado.

Um detalhe importante, é que caso vocês executem a função exatamente como apresentada abaixo em seus computadores, muito provavelmente vocês obterão resultados distintos, uma vez que a seleção dos números é aleatória (até mesmo se vocês executarem o mesmo comando diversas vezes, os resultados serão distintos). Vamos selecionar 5 números aleatórios no intervalo contido entre 2 e 10.

randonA<-runif(n=5, min=2, max=10)

randonA
## [1] 6.677200 9.596761 2.420200 7.469589 4.684560

Caso tenhamos interesse em obter o mesmo resultado do que o apresentado em algum código que utilize a função “runif()”, devemos utilizar uma função denominada “set.seed()”. Essa função cria uma “semente” (um valor) que será utilizado pelo algoritmo criador de números aleatórios presente no R para iniciar o processo. Dessa forma, o resultado final será o mesmo. O argumento informado para a função “set.seed” é qualquer número. Contudo esse número deve ser guardado para que futuramente o mesmo resultado seja obtido. Por exemplo, execute o comando acima da mesma forma que está apresentado e observe o resultado. Note que os números são distintos entre os obtidos por você e os apresentados nesse material. Contudo, se vocês executarem o comando abaixo, e notarem o resultado, verão que o resultado será o mesmo.

set.seed(1234)

randonA<-runif(n=5, min=2, max=10)

randonA
## [1] 2.909627 6.978395 6.874198 6.987036 8.887323


A função “sample()” funciona de maneira semelhante à função “runif()”. Porém, ela permite a seleção de números inteiros, somente. Os argumentos obrigatórios a serem informados à função “sample()” são: x e size. Esses argumentos correspondem ao intervalo de números em que a função selecionará os valores e o número de valores selecionados, respectivamente.

Vamos selecionar 3 valores entre os números 1 e 5 utilizando a função “sample()”.

sampleA<-sample(x=1:5,size=3)

sampleA
## [1] 4 1 5

Note que informando somente esses argumentos, o número de elementos a serem selecionados não pode ser maior do que o intervalo informado. Por exemplo, não seria possível sortear 5 números entre os números 1 e 3.

sampleA<-sample(x=1:3,size=5)
## Error in sample.int(length(x), size, replace, prob): impossível tomar uma amostra maior que a população quando 'replace = FALSE'

Isso se deve a uma característica presente em várias funções do R. Para várias funções, existem argumentos que são obrigatoriamente necessários de serem informados, como no caso de x e size para “sample()”. Porém, a função pode possuir outros argumentos que não precisam ser informados ou que irão receber valores padrão (default) pré-definidos.

A mensagem de erro apresentada pelo comando acima foi: “Error in sample.int(length(x), size, replace, prob): impossível tomar uma amostra maior que a população quando ‘replace = FALSE’”.

Note que a mensagem informa que não é possível fazer esse tipo de amostragem quando o argumento replace= é igual a FALSE. Contudo, não informamos nenhum argumento replace= em nossos comandos. Isso se deve ao fato de que o argumento replace=, quando não informado, recebe um valor padrão pré-determinado, no caso, é um valor condicional (FALSE). Esse argumento realiza “uma pergunta” ao algoritmo sobre a necessidade ou não de repetir números na seleção. Com a resposta padrão sendo FALSE, não podem ser selecionados números repetidos no comando. Contudo, se alterarmos o valor de replace= para TRUE o resultado será o seguinte.

sampleA<-sample(x=1:3,size=5, replace=TRUE)

sampleA
## [1] 2 2 3 2 1

DICA: Os valores condicionais de verdadeiro ou falso no R podem ser informados de duas maneiras: TRUE ou T para verdadeiro e FALSE ou F para falso.


Para a grande maioria das funções presentes no R e em pacotes adicionais, existe uma série de argumento opicionais ou que são utilizados com valores padrão no momento da execução. Para se ter conhecimento de todos os argumentos e como uma função do R funciona, devemos acessar o manual da mesma.

No R, para acessar o manual de uma função devemos posicionar o caracter “?” previamente ao nome da função. Por exemplo, para termos acesso ao manual da função “sample()”, devemos executar o seguinte comando: ?sample().

Por fim, é importante ressaltar que existem diversas alternativas para os comandos acima. Portanto, a prática e a busca por outras formas de se executar a mesma tarefa é algo muito importante para aprimorarmos nossos conhecimentos sobre formas de se utilizar o R.


Criando, identificando e manipulando diferentes tipos de objetos

Além dos vetores, existem outras classes de variáveis muito importantes no R. Nessa parte do curso, iremos introduzir os conceitos sobre esses outros tipos de variáveis e demonstrar como criá-las. Em somatório, iremos discutir como identificar e manipular essas novas classes de variáveis, assim como as descritas anteriormente.

Nos últimos tópicos, algumas formas de criar vetores foram apresentadas. Contudo, durante vários momentos esperamos que o resultado de algum comando que executamos no R crie um vetor. Podemos confirmar se a variável criada trata-se de um vetor por meio de diferentes comandos.

Primeiramente, podemos somente requisitar que o R apresente o conteúdo da variável no console. Com um pouco de prática, somente avaliando a forma da variável torna-se possível de identificar de identificar o tipo. Contúdo, caso a sua varíavel seja muito grande, podemos usar dois comandos muito interessantes e que ajudam na inspeção de variáveis muito longas. Esses comandos são o “head()” e o “tail()”. Esses comandos irão apresentar os seis primeiros e últimos elementos do vetor, respectivamente. Por exemplo, vamos criar um vetor contendo uma sequência que vá de 1 a 100.

#Criando o vetor de 1 a 100 utilizando a função seq()
vetorExemp<-seq(from=1,to=100,by=1)

#Exibindo o resultado do vetor no console
vetorExemp
##   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17
##  [18]  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34
##  [35]  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51
##  [52]  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68
##  [69]  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85
##  [86]  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100
#Utilizando a função head() para apresentar os primeiros seis elementos
head(vetorExemp)
## [1] 1 2 3 4 5 6
#Utilizando a função tail() para apresentar os últimos seis elementos
tail(vetorExemp)
## [1]  95  96  97  98  99 100

Com isso, conseguimos identificar que a variável vetorExemp é um vetor contendo elementos de 1 a 100. Contudo, outras informações podem ser úteis de serem extraídas e/ou confirmadas à partir das variáveis que criamos. Uma delas, por exemplo, é a classe dos elementos inseridos nas variáveis. O R possui pelo menos 4 classes de elementos muito importantes: numeric, character, logical e factor. Saber distinguir cada uma dessas classes é uma tarefa de grande importância, pois existem funções no R que irão aceitar somente uma dessas classes ou que irão se comportar de uma maneira diferente do esperado caso um tipo de classe for usado.

Os objetos que possuem elementos de classe numeric são aqueles que possuem somente números.

Os objetos que possuem elementos de classe character são aqueles que possuem somente caracteres no objeto. Esses objetos podem ser compostos somente por caracteres ou combinações de números e caracteres. Contudo, no segundo caso, os números também serão tratados como caracteres no objeto.

Os objetos que possuem elementos de classe logical são aqueles que possuem somente elementos que representem resultados lógicos (TRUE/T ou FALSE/F).

Os objetos que possuem elementos de classe factor são compostos por números ou caracteres. Contudo, o que diferencia esses elementos é o fato de que eles possuirão uma característica nominal. Ou seja, terão a função de separar o dado em grupos.

Para conferirmos a classe das varíaveis contidas em um objeto podemos utilizar algumas funções nativas do R. Uma dessas funções é a função “str()”. A função “str()” apresenta como output a estrutura da variável utilizada como argumento da função. Iremos utilizá-la para checar todas as variáveis criadas nesse curso dada a sua praticidade e diversidade de detalhes do output. Uma outra possibilidade é utilizarmos a função lógica correspondente a cada elemento. O R possui uma série de funções lógicas para testarmos as características de diversas variáveis e elementos. Basicamente, toda função lógica inicia com o prefixo “is.” seguido do tipo de teste a ser executado. Por exemplo, caso desejamos testar se uma variável possui elementos do tipo numérico, devemos utilizar a função “is.numeric()”. Abaixo serão apresentados alguns exemplos da criação de vetores com essas diferentes classes de elementos, assim como a utilização das funções para testar qual classe foi inserida no vetor.

Vetores numéricos

# Criando um vetor preenchido somente com valores numéricos
vetorNum <- c(1,2,5.3,6,-2,4) 

# Avaliando a estrutura do vetor pela função str()
str(vetorNum)
##  num [1:6] 1 2 5.3 6 -2 4
# Fazendo o teste lógico referente aos elementos inseridos no vetor
is.numeric(vetorNum)
## [1] TRUE

Note que a função “str()” retornou o seguinte output “num [1:6] 1 2 5.3 6 -2 4”. A palavra “num” presente no output indica que o vetor contém elementos numéricos. os valores presentes dentro dos colchetes indicam que existem 6 elementos no vetor (nas posições de 1 a 6). Em seguida são exibidos os números inseridos no vetor. Já a função “is.numeric()” retornou o valor lógico TRUE. Indicando que o vetor contém somente elementos numéricos.


Vetores de caracteres

#Criando um vetor contendo somente caracteres
vetorChracA <- c("one","two","three") 

# Avaliando a estrutura do vetor pela função str()
str(vetorChracA)
##  chr [1:3] "one" "two" "three"
# Fazendo o teste lógico referente aos elementos inseridos no vetor
is.character(vetorChracA)
## [1] TRUE
#Criando um vetor contendo caracteres e números
vetorChracB<- c("one",2,"three") 

# Avaliando a estrutura do vetor pela função str()
str(vetorChracB)
##  chr [1:3] "one" "2" "three"
# Fazendo o teste lógico referente aos alementos inseridos no vetor
is.character(vetorChracB)
## [1] TRUE
#Criando um vetor contendo caracteres numéricos
vetorChracC<- c("1","2","3")

# Avaliando a estrutura do vetor pela função str()
str(vetorChracC)
##  chr [1:3] "1" "2" "3"
# Fazendo o teste lógico referente aos alementos inseridos no vetor
is.character(vetorChracC)
## [1] TRUE

Nos códigos acima foram apresentadas algumas opções de criação de vetores contendo elementos da classe character. É importante ressaltar que a presença da palavra “chr” no output da função “str()” é o que classifica o vetor como possuidor de elementos dessa classe. Na criação dos vetores vetorCharacB e vetorCharacC alguns fatos interessantes devem ser ressaltados. Por exemplo, o vetorCharacB possui um valor numérico (2). Contudo, se observamos o output das funções “str()” e “is.character()”, este valor foi considerado um caracter. O vetor vetorCharacC demonstra que números também podem ser considerados caracteres pelo R. Caso desejamos criar um vetor com uma sequência numérica, porém, também desejamos que essa sequência seja considerada como caracteres, podemos fazer isso simplesmente inserindo cada número entre aspas. Uma alternativa para esse processo é a utilização da função “as.character()”. Essa função irá converter valores numéricos para caracteres. Também existe a função “as.numeric()”. É possível converter o resultado de ambas utilizando a outra função. Por exemplo:

#Criando um vetor contendo caracteres numéricos
vetorChracC<- c(1,2,3)

# Avaliando a estrutura do vetor pela função str()
str(vetorChracC)
##  num [1:3] 1 2 3
# Convertendo o vetor numérico para caracter
vetorChracC<-as.character(vetorChracC)

str(vetorChracC)
##  chr [1:3] "1" "2" "3"
# Convertendo o vetor de caracteres para numérico
vetorChracC<-as.numeric(vetorChracC)

str(vetorChracC)
##  num [1:3] 1 2 3

Note que incialmente o vetorCharacC foi criado como numérico. Em seguida, o mesmo foi convertido com sucesso para a classe character pela função “as.character()”. Em um terceiro momento, o vetor de caracteres foi convertido novamente para numérico pela função “as.numeric()”. Acompanhe as mudanças de classe pelo output da função “str()”.

Vetores lógicos

#Criando o vetor lógico
vetorLogical <- c(TRUE,TRUE,TRUE,FALSE,TRUE) 

# Verificando sua estrutura por meio da função str()
str(vetorLogical)
##  logi [1:5] TRUE TRUE TRUE FALSE TRUE
# Fazendo o teste lógico referente aos alementos inseridos no vetor
is.logical(vetorLogical)
## [1] TRUE

Note que a presença da palavra “logi” no output da função “str()” é o que classifica o vetor como contendo elementos lógicos.

Vetores contendo fatores

Vetores contendo elementos da classe factor possuem características específicas que podem ser muito úteis para várias funções no R. Por exemplo, separar os dados em grupos no momento do cálculo de uma média. Para a criação desse tipo de classe devemos utilizar as funções “factor()” ou “as.factor()”. Abaixo serão apresentados alguns exemplos:

#Criando o vetor de fatores utilizando as classes homem e mulher 
vetorfactorA <- factor(c(rep("homem",3),rep("mulher",3))) 

# Verificando sua estrutura por meio da função str()
str(vetorfactorA)
##  Factor w/ 2 levels "homem","mulher": 1 1 1 2 2 2
vetorfactorA
## [1] homem  homem  homem  mulher mulher mulher
## Levels: homem mulher
#Criando o vetor de fatores utilizando as classes 1 e 2 
vetorfactorB <- factor(c(rep(1,3),rep(2,3))) 

# Verificando sua estrutura por meio da função str()
str(vetorfactorB)
##  Factor w/ 2 levels "1","2": 1 1 1 2 2 2
vetorfactorB
## [1] 1 1 1 2 2 2
## Levels: 1 2

Note que em ambos os casos o output da função “str()” indica que o vetor contém elementos da classe factor. Contudo, algumas novas informações são apresentadas: “Factor w/ 2 levels”homem“,”mulher“: 1 1 1 2 2 2”. A setença “Factor w/ 2 levels”homem“,”mulher“” indica que o vetor é constituído de fatores contendo dois níveis, “homem” e “mulher”. Contudo, os elementos contidos no vetor são apresentado como 1 e 2, sendo 1 referente à “homem” e 2 referente à mulher, isso para o vetorfactorA. No caso do vetorfactorB os níveis são 1 e 2. Esse tipo de dado é bem útil para a classificação de indivíduos em grupos, por exemplo, homem e mulher, caso e controle, etc.


Manipulando e extraindo informações de objetos

A manipulação de objetos no R é um dos tópicos mais importantes durante o aprendizado básico. Saber identificar a posição de elementos dentro de um objeto, extrair esses elementos para alocá-los em outros objetos ou utilizá-los como input de outras funções é uma tarefa extremamente rotineira. Nesse momento iremos trabalhar com a manipulação de elemento em vetores e posteriormente iremos aplicar esses conceitos em outros tipos de variáveis no R.

Como exemplo, vamos criar um vetor contendo 6 elementos compostos pelos números 1, 2 e 3 de maneira duplicada.

vetorExemp<-c(1,2,3,1,2,3)

vetorExemp
## [1] 1 2 3 1 2 3

A identificação de elementos em vetores (assim como nos outros tipos de variáveis no R) é realizada por meio da utilização de colchetes . Os colchetes são utilizados para informar os índices (posições) dos elementos dentro do vetor. Por exemplo, vamos extrair os elementos nas posições 2 e 4 do vetorExemp, e solicitar que os elementos correspondentes sejam informados no console.

vetorExemp[c(2,4)]
## [1] 2 1

Note que os elementos 2 e 1 foram apresentados no console. O mesmo pode ser feito para se obter elementos em qualquer outra posição.

Agora, vamos extrair esses elementos e inseridos em um novo vetor.

newVetorExemp<-vetorExemp[c(2,4)]

newVetorExemp
## [1] 2 1

Com esse comando, os elementos 2 e 1 foram inseridos no vetor newVetorExemp.


Em determinados momentos podemos ter o interesse de executar o processo contrário. Ou seja, identificar as posições dentro de um vetor que correspondam a um determinado valor. Esse processo pode ser feito de maneira muito simples, utilizando o operador “==”.

IMPORTANTE: Devemos utilizar o operador “==” devido ao fato do operador “=” ser utilizado para criar objetos.

vetorExemp==2
## [1] FALSE  TRUE FALSE FALSE  TRUE FALSE

Note que o comando acima retorna uma série de elementos lógicos informando se o elemento na determinada posição é igual a 2 (TRUE) ou não (FALSE). Para determinarmos qual a posição destes elementos, podemos usar dentre outras possibilidades, a função “which()”.

which(vetorExemp==2)
## [1] 2 5

Note agora que o output dessa função retorna as posições dos elementos igual a 2 no vetor vetorExemp.


Combinando os comandos acima, podemos realizar uma tarefa que pode ser de grande ajuda para a construção de rotinas complexas e análise de dados no R, que é a extração de sub-conjuntos de dados de um vetor que sejam correspondentes a um valor.

Por exemplo, utilizando o vetorExemp e os comandos descritos acima, vamos criar um vetor contendo somente os valores 2.

Uma forma de executar esse comando seria:

vetorExemp[vetorExemp==2]
## [1] 2 2

Desta forma, o R irá interpretar o resultado da comparação lógica realizada pelo comando “vetorExemp==2” de uma maneira que os índices onde o resultado seja igual a TRUE serão utilizados para determinar os elementos a serem exibidos no console.

Esse mesmo procedimento pode ser feito de diferentes maneiras. Abaixo serão mostradas algumas formas.

Podemos utilizar o comando “which()” para informar diretamente as posições a serem extraída:

vetorExemp[which(vetorExemp==2)]
## [1] 2 2

Podemos armanezar as posições dentro de um vetor e utiliza-lo para realizar a busca pelos índices correspondentes:

vetorPos<-which(vetorExemp==2)

vetorPos
## [1] 2 5
vetorExemp[vetorPos]
## [1] 2 2

Note que o resultado do vetorPos apresenta as posições dentro do vetorExemp que possuem elementos iguais a 2.


Note que todos os comandos tiveram os mesmos resultados. Cada uma dessas formas terá suas vantagens e desvantagens no momento da análise. Cabe a nós definir qual a melhor estratégia de aplicação no momento da criação de nossos algoritmos. Contudo, é importante saber que existem diferentes formas de se realizar indexação (identificar a posição de elementos) de elementos no R.

Um outra aplicação muito importante do processo de indexação é a substituição e remoção de elementos em um vetor. Usando a mesma lógica, podemos identificar as posições de todos os elementos de um vetor que sejam iguais a um determinado padrão e substituí-los por um outro elemento. Por exemplo, utilizando o vetorExemp, vamos identificar todos os elementos igual a 2 e substituí-los por NA.

DICA: O NA é uma palavra que possui um significado próprio no R. O NA é resposável por representar missing data. Ou seja, valores que não foram informados ou coletados. Outra palavra com significado próprio é o NaN, que corresponde ao resultado de operações impossíveis, como por exemplo, divisões por zero. No módulo em que iremos discutir sobre bases de dados iremos trabalhar um pouco mais sobre o conceito de missing data e como contornar os possíveis problemas ocasionados pela presença dos mesmos.

# Apresentando os valores do vetor vetorExemp no console
vetorExemp
## [1] 1 2 3 1 2 3
# Substituindo todos os valores iguais a 2 por NA
vetorExemp[vetorExemp==2]<-NA

# Apresentando os novos valores do vetor vetorExemp
vetorExemp
## [1]  1 NA  3  1 NA  3

Note que todos os valores iguais a 2 foram substituídos por NA. Essa mesma lógica pode ser aplicada para a substituição de qualquer valor dentro do elemento.

Existe um operador muito útil para ser aplicado na busca por padrões em vetores. Este operador é o “|”. Na linguagem de programação do R, o “|” significa “ou”. Desta forma, podemos buscar por mais de um padrão para ser substituído. Por exemplo, vamos substituir todos os elementos iguais a 2 ou 3 por 1.

# Apresentando os valor do vetor vetorExemp no console
vetorExemp
## [1] 1 2 3 1 2 3
# Substituindo todos os valores igual a 2 e 3 por 1
vetorExemp[vetorExemp==2 | vetorExemp==3]<-1

# Apresentando os novos valores do vetor vetorExemp
vetorExemp
## [1] 1 1 1 1 1 1

Note que os dois padrões foram combinados para que todos os elementos iguais a 2 ou 3 fossem substituídos.


Por meio da indexação de elementos também podemos inserir e remover elementos em vetores. Por exemplo, o vetor vetorExemp possui seis elementos. Utilizando a indexação podemos inserir um sétimo elemento no vetor. Vamos inserir o número 10 como sétimo elemento do vetor.

# Criando o vetor contendo seis elementos como anteriormente
vetorExemp<-c(1,2,3,1,2,3)

# Apresentando os elementos presentes no vetor
vetorExemp
## [1] 1 2 3 1 2 3
# Inserindo o sétimo elemento (10) no vetor
vetorExemp[7]<-10

# Apresentando os novos elementos contidos no vetor
vetorExemp
## [1]  1  2  3  1  2  3 10

Da mesma forma, podemos inserir quantos elementos quisermos. Por exemplo, vamos inserir 10 elementos constituindo uma sequência de 10 a 20, no vetor vetorExemp original.

# Criando o vetor contendo seis elemento, como anteriormente
vetorExemp<-c(1,2,3,1,2,3)

# Apresentando os elementos presentes no vetor
vetorExemp
## [1] 1 2 3 1 2 3
# Inserindo o inserindo 10 elementos a partir do sétimo elemento no vetorr
vetorExemp[7:17]<-seq(from=10, to=20,by=1)

# Apresentando os novos elementos contidos no vetor
vetorExemp
##  [1]  1  2  3  1  2  3 10 11 12 13 14 15 16 17 18 19 20

Note que o número de posições informadas nos colchetes " é referente ao número de elementos a serem inseridos.


Uma outra aplicação muito importante da indexação é a remoção de elementos dos vetores. Isso pode ser feito pela simples inclusão do operador “-” precedendo a posição informada. Por exemplo, utilizando o vetor vetorExemp original, vamos remover o elemento na quarta posição.

# Criando o vetor contendo seis elementos como anteriormente
vetorExemp<-c(1,2,3,1,2,3)

# Apresentando os elementos presentes no vetor
vetorExemp
## [1] 1 2 3 1 2 3
# Removendo o elemento na quarta posição
vetorExemp[-4]
## [1] 1 2 3 2 3

Note que o número 1 anteriormente presente na quarta posição do vetor foi excluído.

O mesmo pode ser aplicado para múltiplas posições utilizando a função “c()”. Por exemplo, vamos excluir as posições 3 e 5 do vetor anterior.

# Criando o vetor contendo seis elementos como anteriormente
vetorExemp<-c(1,2,3,1,2,3)

# Apresentando os elementos presentes no vetor
vetorExemp
## [1] 1 2 3 1 2 3
# Removendo o elemento na quarta posição
vetorExemp[-c(3,5)]
## [1] 1 2 1 3

Também podemos combinar a busca recursiva pela posição dos elementos com a exclusão dos mesmos. Por exemplo, utilizando o vetor vetorExemp original, vamos remover todos os elementos iguais a 2.

# Criando o vetor contendo seis elementos como anteriormente
vetorExemp<-c(1,2,3,1,2,3)

# Apresentando os elementos presentes no vetor
vetorExemp
## [1] 1 2 3 1 2 3
# Removendo todos os elementos iguais a 2
vetorExemp[-which(vetorExemp==2)]
## [1] 1 3 1 3

Note que para que isso fosse possível, tivemos que utilizar a função “which()”, que informa a posição dos elementos lógicos iguais a TRUE que foram criados pelo comando “vetorExemp==2”. Caso tentassemos posicionar o operador “-” diretamente com o comando “vetorExemp==2”, uma mensagem de erro seria informada.


Todos os comandos e dicas apresentadas acima podem ser aplicadas a diversos outros tipos de variáveis no R (algumas vezes alterando pequenos detalhes). A seguir, vamos aprender um pouco sobre outros tipos de variáveis muito comuns na utilização do R e iremos aplicar alguns dos comandos descritos acima para identificação e manipulação de dados.


Além dos vetores, existem outros tipos de objetos muito úteis e constantemente utilizados no R. Esses objetos são as matrizes, data frames, arrays e listas. Cada um deles possui suas peculiaridades, que os tornam objetos muito úteis para o armazenameno de diferentes tipos de dados.

Matrizes

As matrizes são objetos que armazenam informações homogêneas em duas dimensões. Porém, o que significam essas características? A característica das matrizes armazenarem informações homogeneas é devido ao fato das mesmas somente serem capazes de armazenar informações de uma única classe de elementos (numeric, character, factor, logical). O armazenamento dos dados em duas dimensões se dá pela presença de linhas e colunas nesse tipo de objeto.

A presença de linhas e colunas garante algumas características diferenciadas para as matrizes quando comparadas aos vetores, vistos anteriormente. As matrizes podem ser criadas no R através do comando “matrix()”. Os argumentos que devem ser informados para esse comando são: “data=”, “nrow=”, “ncol=”. O argumento “data=” corresponde aos dados que são inseridos na matriz. É importante ressaltar que nesse caso, o número de informações deve corresponder ao número de linhas e colunas criados na matriz pelos comandos “nrow=” e “ncol=”, respectivamente. Por exemplo, se criarmos uma matriz com 3 linhas e 3 colunas, devemos informar 9 elementos a serem preenchidos na matriz.

# Criando uma matriz contendo 3 linhas e 3 colunas e preenchendo com valores de 1 a 9
matrizA<-matrix(data=1:9, nrow=3, ncol=3)

# Apresentando a matriz criada, no console
matrizA
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9

Note que os números foram preenchidos na matriz utilizando as colunas. Os números de 1 a 3 foram armazenadas na primeira coluna, de 4 a 6 na segunda e 7 a 9 na terceira. Isso é devido a um argumento que quando não informado, é considerado em seu valor default pela função “matrix()”. Esse argumento é chamado de “byrow=”. Esse argumento recebe um valor lógico (TRUE/T ou FALSE/F) informando se os valores devem ser preenchidos na matriz utilizando as linhas. O default é FALSE, ou seja, os valores não serão preenchidos utilziando as linhas, mas sim as colunas. Podemos mudar esse comportamento determinando o valor informado para o argumento como TRUE.

# Criando uma matriz contendo 3 linhas e 3 colunas e preenchendo com valores de 1 a 9 (preenchendo utilizando as linhas)
matrizA<-matrix(data=1:9, nrow=3, ncol=3, byrow=TRUE)

# Apresentando a matriz criada, no console
matrizA
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9

Compare as duas matrizes A criadas e veja a diferença.

Também podemos testar se o objeto criado realmente trata-se de uma matriz. Para isso, podemos utilizar as seguintes opções:

# Criando uma matriz contendo 3 linhas e 3 colunas e preenchendo com valores de 1 a 9
matrizA<-matrix(data=1:9, nrow=3, ncol=3)

# Utilizando a função class()
class(matrizA)
## [1] "matrix"
# Utilizando a função is.matrix()
is.matrix(matrizA)
## [1] TRUE
# Utilizando a função str()
str(matrizA)
##  int [1:3, 1:3] 1 2 3 4 5 6 7 8 9

A função “class()” informa diretamente qual é a classe do objeto utilizado como argumento da função. No caso, é informado que trata-se de uma matriz (“matrix”). A função “is.matrix()” executa um teste lógico e retorna TRUE no caso do objeto ser uma matriz, o que aconteceu no caso. Já a função “str()” não informa diretamente que trata-se de uma matriz, mas podemos inferir pelo tipo de indexação utilizada para representar os dados. O output apresenta a palavra “int” indicando que os dados inseridos na matriz são numéricos inteiros e após os as informações sobre a dimensão da matriz ([1:3,1:3]) é exibido o conteúdo da matriz. Contudo, a grande diferença fica na forma como são apresentados os índices dos valores dentro dos colchetes .

Pelo fato das matrizes possuírem duas dimensões (linhas e colunas), o sistema de indexação é ligeiramente distinto. Como foi possível notar no output da função “str()”, existe uma vírgula dentro dos colchetes, separando os números. Com essa estrutura somos capazes de informar os índices das linhas (à esquerda da vírgula) e os índices das colunas (à direita da vírgula).

Por exemplo, utilizando a matrizA criada preenchendo os dados pelas colunas, vamos recuperar o valor alocado na primeira linha e na segunda coluna da matriz criada.

# Criando uma matriz contendo 3 linhas e 3 colunas e preenchendo com valores de 1 a 9
matrizA<-matrix(data=1:9, nrow=3, ncol=3)

# Extraindo o elemento alocado na primeira linha e segunda coluna da matriz
matrizA[1,2]
## [1] 4

Note que o número 4 é o elemento presente nessa posição. Tente mudar os valores presentes dentro dos colchetes para verificar quais números são informados.

Esse processo de indexação é muito útil para várias funções, com ele podemos estrair subconjuntos de uma matrix e criarmos uma outra matriz contendo esse subconjunto de linhas e colunas.

Por exemplo, vamos criar uma sub-matrix contendo todas as linhas e apenas as colunas 1 e 3 da matriz original (matrizA).

# Criando uma matriz contendo 3 linhas e 3 colunas e preenchendo com valores de 1 a 9
matrizA<-matrix(data=1:9, nrow=3, ncol=3)

# Apresentando os valores contidos na matrizA

matrizA
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
# Extraindo o subconjunto de linhas e colunas para alocá-lo na nova matriz
subMatrizA<-matrizA[,c(1,3)]

# Apresentando os valores inseridos na sub-matriz criada
subMatrizA
##      [,1] [,2]
## [1,]    1    7
## [2,]    2    8
## [3,]    3    9

Note que na sub-matriz criada, todas as linhas foram mantidas. Contudo, somente as colunas selecionadas estão presentes. A ausência de valores à esquerda da vírgula é interpretado como um comando para que todas as linhas sejam utilizadas. O mesmo pode ser aplicado para selecionar todas as colunas e algumas linhas. Tente relizar esse procedimento.

Também é possível excluir linhas e colunas das matrizes utilizando o operador “-”. Por exemplo:

# Criando uma matriz contendo 3 linhas e 3 colunas e preenchendo com valores de 1 a 9
matrizA<-matrix(data=1:9, nrow=3, ncol=3)

# Apresentando os valores contidos na matrizA

matrizA
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
# Eliminando a coluna 2 da matrizA e apresentando o resultado no console
matrizA[,-2]
##      [,1] [,2]
## [1,]    1    7
## [2,]    2    8
## [3,]    3    9
# Eliminando a linha 3 da matrizA e apresentando o resultado no console
matrizA[-3,]
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8

Para facilitar a identificação dos dados inseridos nas matrizes, podemos adicionar nomes para as linhas e colunas das matrizes. Vamos criar abaixo uma matriz contendo dados para 3 variáveis (posicionadas nas colunas) e 4 indivíduos (posicionados nas linhas).

#Criando a matrix
matrizB<-matrix(data=c(1,0,1,1,0,0,0,1,1,1,0,0), ncol=3, nrow=4)

#Apresentando os valores contidos na matrix
matrizB
##      [,1] [,2] [,3]
## [1,]    1    0    1
## [2,]    0    0    1
## [3,]    1    0    0
## [4,]    1    1    0

Após a criação da matriz, vamos nomear as linhas e as colunas utilizando as funções “rownames()” e “colnames()”, respectivamente.

# Nomeando as linhas da matriz criada anteriormente
rownames(matrizB)<-c("Ind1", "Ind2", "Ind3", "Ind4")

# Nomeando as colunas da matriz criada anteriormente
colnames(matrizB)<-c("Variavel_1", "Variavel_2", "Variavel_3")

# Apresentando a matriz com as linhas e colunas nomeadas
matrizB
##      Variavel_1 Variavel_2 Variavel_3
## Ind1          1          0          1
## Ind2          0          0          1
## Ind3          1          0          0
## Ind4          1          1          0

Note como as colunas e linhas agora possuem os nomes informados. Também é possível informar o nome das colunas e linhas diretamente como um argumento da função “matrix()”. Contudo, para isso, necessitamos ter o conhecimento de como funcionam objetos do tipo list. Nos próximos tópicos iremos abordar esse tipo de elemento e voltaremos à criação de matrizes para mostrar essa aplicação.

Podemos aplicar o mesmo sistema de busca por valores inseridos nas matrizes para realizar as edições necessárias. Por exemplo, vamos substituir todos os valores iguais a zero por 10 na matriz anterior.

# Apresentando a matriz com as linhas e colunas nomeadas
matrizB
##      Variavel_1 Variavel_2 Variavel_3
## Ind1          1          0          1
## Ind2          0          0          1
## Ind3          1          0          0
## Ind4          1          1          0
# Substituindo os valores iguais a zero por 10
matrizB[matrizB==0]<-10

#Apresentando a matriz com os novos valores

matrizB
##      Variavel_1 Variavel_2 Variavel_3
## Ind1          1         10          1
## Ind2         10         10          1
## Ind3          1         10         10
## Ind4          1          1         10

É possível combinar a identificação de posições de elementos específicos, aprendido anteriormente utilizando vetores, com a seleção de subconjuntos nas matrizes. Isso é feito de uma maneira bem simples. Uma das formas de realizar esse procedimento é encontrar o padrão especificado em uma coluna e inserí-lo em um novo elemento. Por exemplo, utilizando a matriz criada anteriormente, vamos criar uma sub-matrix contendo todas as colunas, porém, somente aquelas linhas que tiverem um valor igual a 10 na coluna “Variavel_3”.

# Apresentando a matriz com as linhas e colunas nomeadas
matrizB
##      Variavel_1 Variavel_2 Variavel_3
## Ind1          1         10          1
## Ind2         10         10          1
## Ind3          1         10         10
## Ind4          1          1         10
# Obtendo uma submatriz à partir das linhas que possuem elementos iguais a 10 na coluna Variavel_3
submatrizB<-matrizB[which(matrizB[,"Variavel_3"]==10),]

#Apresentando a sub-matriz criada

submatrizB
##      Variavel_1 Variavel_2 Variavel_3
## Ind3          1         10         10
## Ind4          1          1         10

Note que eu optei por utilizar a função “which()” juntamente com o comando “matrizB$Variavel_3==10”. Essa escolha foi feita pois utilizando a função “which()”, podemos também remover essas linhas utilizando o operador “-”. Observe como o output contido na submatrizB possui somente as linhas selecionadas à partir do conteúdo da coluna “Variavel_3”. Esse é um procedimento muito útil para a filtragem e manuseio de base de dados.

Outra função muito útil enquanto estamos lidando com matrizes é a função “t()”. Essa função está relacionada à ação de transpor o conteúdo da matriz. Ela é muito simples de ser aplicada. O único argumento a ser informado é uma matriz. Vamos utilizar a matrizB originalmente criada para exemplificar o processo.

#Criando a matrix
matrizB<-matrix(data=c(1,0,1,1,0,0,0,1,1,1,0,0), ncol=3, nrow=4)

# Nomeando as linhas da matriz criada anteriormente
rownames(matrizB)<-c("Ind1", "Ind2", "Ind3", "Ind4")

# Nomeando as colunas da matriz criada anteriormente
colnames(matrizB)<-c("Variavel_1", "Variavel_2", "Variavel_3")

#Apresentando a matrizB original
matrizB
##      Variavel_1 Variavel_2 Variavel_3
## Ind1          1          0          1
## Ind2          0          0          1
## Ind3          1          0          0
## Ind4          1          1          0
#Trnaspondo a matrizB criada
transMatrizB<-t(matrizB)

# Apresentando o resultado no console

transMatrizB
##            Ind1 Ind2 Ind3 Ind4
## Variavel_1    1    0    1    1
## Variavel_2    0    0    0    1
## Variavel_3    1    1    0    0

Matrizes são objetos muito úteis para armazenar e realizar operações no R. Todo o tipo de operação envolvendo álgebra matricial é possível de ser realizada no R. Contudo, o nosso curso não terá um enfoque nessa área.

Data Frames

As Data Frames são um tipo de objeto muito importante no R. Assim como as matrizes, as Data Frames são organizadas em uma estrutura bidimensional. Contudo, elas permitem a presença de elementos heterogêneos. Ou seja, mais de uma classe de elementos podem estar presentes. Data Frames não passam de tabelas dentro do ambiente do R. Portanto, serão constantemente utilizados por nós.

Todos os procedimentos descritos acima para as matrizes são aplicáveis para as Data Frames.

DICA: As colunas e linhas contidas em marizes ou Data Frames no R possuem as mesmas características de vetores. Ou seja, cada linha e cada coluna em uma matriz ou Data Frame é um vetor. Portanto, podemos aplicar todos os procedimentos descritos acima para cada uma delas.

A criação de Data Frames no R se dá pela utilização da função “data.frame()”. A forma de utilização dessa função é bem específica e utiliza o conceito descrito acima, onde cada linha e coluna da Data Frame é um vetor. Como argumentos básicos da função “data.frame()” devemos informar os vetores que constituirão as colunas da tabela. Por exemplo, vamos criar uma Data frame contendo 3 variáveis (posicionadas nas colunas) e 4 indivíduos (posicionados nas linhas), assim como na matrizB.

#Criando a Data Frame contendo 3 colunas e 4 linhas
dataframeA<-data.frame(Variavel_1=c(1,0,1,1), Variavel_2=c(0,0,0,1), Variavel_3=c(1,1,0,0))

#Apresentando o conteúdo da Data Frame criada
dataframeA
##   Variavel_1 Variavel_2 Variavel_3
## 1          1          0          1
## 2          0          0          1
## 3          1          0          0
## 4          1          1          0

Note que pelo fato de informarmos o nome das variáveis que compuseram as colunas da Data Frame nossa tabela já possui o nome das colunas. Podemos adicionar o nome das linhas simplesmente utilizando a função “rownames()”.

#Criando a Data Frame contendo 3 colunas e 4 linhas
rownames(dataframeA)<-c("ind1", "ind2", "ind3", "ind4")

#Apresentando o conteúdo da Data Frame criada
dataframeA
##      Variavel_1 Variavel_2 Variavel_3
## ind1          1          0          1
## ind2          0          0          1
## ind3          1          0          0
## ind4          1          1          0

Note que agora as linhas também estão nomeadas.

Para entendermos um pouco mais sobre a estrutura das Data Frames, vamos utilizar um dos diversos exemplos contidos no R e que podem ser importados utilizando a função “data()”. A Data Frame que vamos utilizar como exemplo será a “mtcars” que contém informações extraídas à respeito da performance de carros no período de 1973-1974 e publicados na revista Motor Trend US.

# Importando a Data Frame mtcars para um objeto chamado dataframe_mtcars
data(mtcars)
dataframe_mtcars<-mtcars

# Apresentando as seis primeiras linhas de todas as colunas da Data Frame
head(dataframe_mtcars)
##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

Note que existem modelos de carros contidos nas linhas e algumas variáveis contidas nas colunas. Porém, quantas observações possuímos nessa tabela? Podemos extrair essa informação utilizando a função “dim()”. Essa função apresentará as dimensões da tabela (ou matriz, ou qualquer objeto de duas dimensões), ou seja, o número de linhas e colunas.

dim(dataframe_mtcars)
## [1] 32 11

Note que possuimos 32 observações (32 modelos de carros) que são avaliados em função de 11 variáveis. Caso você tenha interesse de encontrar uma descrição sobre cada variável, você pode acessar o material contendo a descrição dessa base de dados por meio do comando “?mtcars”.

Uma descrição mais completa das dimensões da tabela, assim como a classe de cada coluna presente na base de dados pode ser acessada pelo comando “str()”.

str(dataframe_mtcars)
## 'data.frame':    32 obs. of  11 variables:
##  $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
##  $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
##  $ disp: num  160 160 108 258 360 ...
##  $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
##  $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
##  $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
##  $ qsec: num  16.5 17 18.6 19.4 17 ...
##  $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
##  $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
##  $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
##  $ carb: num  4 4 1 1 2 1 4 2 2 4 ...

Note que o comando descreve que a base de dados contém 32 observações para 11 variáveis, logo no começo do output. Em seguida, existe uma breve descrição da classe dos elementos contidos em cada coluna. Nesse caso, todos são numéricos. Seguido dessa classificação é possível ver uma apresentação dos primeiros elementos alocados em cada coluna.

Utilizando a base de dados mtcars, vamos aplicar alguns procedimentos de manipulação de dados em Data Frames. A segunda coluna da base de dados mtcars contém o número de cilindros que cada carro possui. Vamos aplicar um filtro nessa coluna (“cyl”) para que uma nova Data Frame seja criada somente com os carros possuidores de 6 ou mais cilindros. Além disso, vamos criar uma terceira Data Frame contendo aqueles carros com menos de 6 cilíndros.

# Criando uma nova Data Frame contendo somente aqueles carros possuidores de 6 ou mais cilindros.
MaisSeisCyl<-dataframe_mtcars[which(dataframe_mtcars$cyl>=6),]
MaisSeisCyl
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
# Criando uma nova Data Frame contendo somente aqueles carros possuidores de menos de 6 cilindros.
MenosSeisCyl<-dataframe_mtcars[which(dataframe_mtcars$cyl<6),]
MenosSeisCyl
##                 mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Datsun 710     22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Merc 240D      24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Merc 230       22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Fiat 128       32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## Honda Civic    30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Toyota Corolla 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## Toyota Corona  21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Fiat X1-9      27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## Porsche 914-2  26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Lotus Europa   30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Volvo 142E     21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

DICA: O operador (\() é utilizado para selecionar uma coluna presente em uma *Data Frame*. Portando, o comando dataframe_mtcars\)cyl está informando que a operação a seguir será realizada com a coluna “cyl” presente na Data Frame. Dessa forma, conseguimos trabalhar com a coluna com o mesmo comportamento de um vetor.

O mesmo resultado pode ser obtido utilizando o operador “-”

# Criando uma nova Data Frame contendo somente aqueles carros possuidores de 6 ou mais cilindros.
MaisSeisCyl<-dataframe_mtcars[-which(dataframe_mtcars$cyl<6),]
MaisSeisCyl
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
# Criando uma nova Data Frame contendo somente aqueles carros possuidores de menos de 6 cilindros.
MenosSeisCyl<-dataframe_mtcars[-which(dataframe_mtcars$cyl>=6),]
MenosSeisCyl
##                 mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Datsun 710     22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Merc 240D      24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Merc 230       22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Fiat 128       32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## Honda Civic    30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Toyota Corolla 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## Toyota Corona  21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Fiat X1-9      27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## Porsche 914-2  26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Lotus Europa   30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Volvo 142E     21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

Note que apesar da sutil diferença, o mesmo resultado foi obtido em ambas as formas.

Aqui foram apresentados alguns conceitos básicos sobre Data Frames. Tente aplicar os conceitos de algumas das funções apresentadas para vetores e matrizes nas Data Frames. Por exemplo “tai()”, “t()”, “class()”, “is.dataframe()”, etc…

Nós teremos um módulo destinado somente à importação de tabelas no R. Nesse módulo poderemos trabalhar mais a fundo algumas especificidades das Data Frames, assim como entender seu funcionamento em operações e manipulações dos mais diversos tipos.

Listas

As listas talvez sejam os objetos mais versáteis no R. Elas são capazes de armazenar diversos outros tipos de objetos em uma única variável. Isso permite que agrupemos uma diversidade muito grande de informação em um único objeto. Desta forma, facilitando nossa organização e processamento dos dados.

As listas podem ser criadas utilizando a função “list()”. Nesse caso, precisamos informar somente o nome de cada seção da lista a ser criada e o respectivo objeto que será inserido nessa seção. Por exemplo, vamos inserir em uma lista os objetos vetorExemp, matrizA e dataframe_mtcars criados anteriormente.

Primeiro vamos relembrar como cada um desses objetos foram criados:

#Criando o vetor de 1 a 100 utilizando a função seq()
vetorExemp<-seq(from=1,to=100,by=1)

# Criando uma matriz contendo 3 linhas e 3 colunas e preenchendo com valores de 1 a 9
matrizA<-matrix(data=1:9, nrow=3, ncol=3)

# Importando a Data Frame mtcars para um objeto chamado dataframe_mtcars
data(mtcars)
dataframe_mtcars<-mtcars

Em seguida, vamos criar a lista:

#Criando a lista contendo todos os elementos descritos anteriormente
listA<-list(vetor=vetorExemp, matriz=matrizA, Data_Frame=dataframe_mtcars)

#Apresentando o conteúdo da lista no console
listA
## $vetor
##   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17
##  [18]  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34
##  [35]  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51
##  [52]  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68
##  [69]  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85
##  [86]  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100
## 
## $matriz
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
## 
## $Data_Frame
##                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
## Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
## Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
## Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
## Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
## Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
## Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
## Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
## Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
## Chrysler Imperial   14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
## Fiat 128            32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
## Honda Civic         30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
## Toyota Corolla      33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
## Toyota Corona       21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
## Dodge Challenger    15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
## AMC Javelin         15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
## Camaro Z28          13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4
## Pontiac Firebird    19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
## Fiat X1-9           27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
## Porsche 914-2       26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
## Lotus Europa        30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
## Ford Pantera L      15.8   8 351.0 264 4.22 3.170 14.50  0  1    5    4
## Ferrari Dino        19.7   6 145.0 175 3.62 2.770 15.50  0  1    5    6
## Maserati Bora       15.0   8 301.0 335 3.54 3.570 14.60  0  1    5    8
## Volvo 142E          21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

Note como todos os elementos estão posicionados na listA.

O processo de indexação utilizando listas é um pouco diferente do convencional utilizado por outros tipos de objetos. Contudo, a lógica é a mesma. Devemos utilizar a posição dentro de colchetes . Contudo, se utilzarmos somente um colchete para abrir e fechar o entorno da posição, um “pedaço” da lista será exibido:

# Exibindo o primeiro elemento da lista
listA[1]
## $vetor
##   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17
##  [18]  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34
##  [35]  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51
##  [52]  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68
##  [69]  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85
##  [86]  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100

Note que o output começa com o “Vetor”, indicando que estamos visualizando o primeiro elemento da lista. Essa estrutura é útil para filtrarmos os elementos da lista. Contudo, com ela, não é possível referenciarmos os elementos contidos nesse primerio elemento da lista. Por exemplo, utilizando somente listA[1] não conseguiríamos acessar os primeiros 10 elementos de “Vetor”. Para que isso seja possível, devemos utilizar colchetes duplos, seguidos de colchetes simples. Essa é uma estrutura um pouco estranha, mas iremos exemplificar logo abaixo. Por exemplo, vamos extrair as 10 primeiras posições de “Vetor”:

# Exibindo os 10 primeiros elementos de $Vetor
listA[[1]][1:10]
##  [1]  1  2  3  4  5  6  7  8  9 10

Tente utilziar a mesma estrutura para apresentar outras partes do mesmo vetor.

O mesmo pode ser aplicado para as matrizes e Data Frames contidas nas listas. Por exemplo, vamos exibir as 10 primeiras linhas e 5 primeiras colunas da Data Frame contida na lista. Lembrando que ela encontra-se na terceira posição da lista.

# Exibindo as 10 primeiras linhas e as 5 primeiras colunas de $Data_Frame
listA[[3]][1:10,1:5]
##                    mpg cyl  disp  hp drat
## Mazda RX4         21.0   6 160.0 110 3.90
## Mazda RX4 Wag     21.0   6 160.0 110 3.90
## Datsun 710        22.8   4 108.0  93 3.85
## Hornet 4 Drive    21.4   6 258.0 110 3.08
## Hornet Sportabout 18.7   8 360.0 175 3.15
## Valiant           18.1   6 225.0 105 2.76
## Duster 360        14.3   8 360.0 245 3.21
## Merc 240D         24.4   4 146.7  62 3.69
## Merc 230          22.8   4 140.8  95 3.92
## Merc 280          19.2   6 167.6 123 3.92

Podemos usar alguns dos comandos descritos acima para identificar a estrutura dos dados contidos na lista:

# A função length() irá apresentar o número de elementos contidos na lista
length(listA)
## [1] 3
# A função str() apresentará a esturura geral da lista
str(listA)
## List of 3
##  $ vetor     : num [1:100] 1 2 3 4 5 6 7 8 9 10 ...
##  $ matriz    : int [1:3, 1:3] 1 2 3 4 5 6 7 8 9
##  $ Data_Frame:'data.frame':  32 obs. of  11 variables:
##   ..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
##   ..$ cyl : num [1:32] 6 6 4 6 8 6 8 4 4 6 ...
##   ..$ disp: num [1:32] 160 160 108 258 360 ...
##   ..$ hp  : num [1:32] 110 110 93 110 175 105 245 62 95 123 ...
##   ..$ drat: num [1:32] 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
##   ..$ wt  : num [1:32] 2.62 2.88 2.32 3.21 3.44 ...
##   ..$ qsec: num [1:32] 16.5 17 18.6 19.4 17 ...
##   ..$ vs  : num [1:32] 0 0 1 1 0 1 0 1 1 1 ...
##   ..$ am  : num [1:32] 1 1 1 0 0 0 0 0 0 0 ...
##   ..$ gear: num [1:32] 4 4 4 3 3 3 3 4 4 4 ...
##   ..$ carb: num [1:32] 4 4 1 1 2 1 4 2 2 4 ...
# A função class() será utilizada para apresentar a classe do objeto 
class(listA) 
## [1] "list"
# A função names() apresenta o nome de cada elemento presente na lista
names(listA)
## [1] "vetor"      "matriz"     "Data_Frame"

Note que nos exemplos acima, uma nova função foi apresentada. Trata-se da função “length()”. Esta função pode ser aplicada praticamente a qualquer objeto no R e irá reportar o número de elementos no objeto. No caso da listA, existem 3 elementos na lista. O comando “str()” já é conhecido por nós. Contudo, no caso das listas, ele irá apresentar uma descrição do número de elementos contidos na lista (“List of 3”, no caso) e uma descrição de cada objeto contido na lista. A função class confirma que estamos analisando uma lista pelo seu output. Já a função “names()”, também nova para nós, apresenta o nome de cada objeto contido na lista.

Um exemplo da utilização da função “list()” dentro de outras funções é a opção de determinar o nome das linhas e colunas diretamente na função “matrix()”. Para isso, devemos usar o argumento “dimnames=”. Veja um exemplo abaixo:

#Criando a matrix
matrizB<-matrix(data=c(1,0,1,1,0,0,0,1,1,1,0,0), ncol=3, nrow=4, dimnames=list(c("Ind1", "Ind2", "Ind3", "Ind4"),c("Variavel_1", "Variavel_2", "Variavel_3")))

#Apresentando os valores contidos na matrix
matrizB
##      Variavel_1 Variavel_2 Variavel_3
## Ind1          1          0          1
## Ind2          0          0          1
## Ind3          1          0          0
## Ind4          1          1          0

Note que a matrizB criada com esse comando já possui os nomes das linhas e colunas.

Nesse módulo apresentamos uma série de dicas relacionadas à criação, manipulação e edição básicas de objetos no R. Ao longo dos próximos módulos iremos aplicar esses conceitos de maneira prática por meio de criação/edição de bancos de dados, análise de estatística descritiva e criação de gráficos. É muito importante que esta parte fique bem fundamentada para que os próximos tópicos sejam entendidos de maneira mais simples.