Ferramentas do usuário

Ferramentas do site


02_tutoriais:tutorial3:start

3. Tutoriais de Leitura e Manipulação de dados no R

Os 10 mandamentos do R Agora que já tem alguma experiência com a linguagem, veja os 10 mandamentos do R! Ao final do curso revisite esses mandamentos e avalie quantos pecados deve confessar.

Objetos de Dados

Vetores como estrutura básica de dados

Nos tutoriais anteriores, nós usamos uma classe de objetos que é a estrutura básica de armazenamento de de dados no R, a classe de objetos vetores. Vamos criar um vetor de dados numéricos, chamado “num”, que seja uma sequência de valores de 0 a 15 divididos em 7 valores equidistantes.

| Criando Vetor
num <- seq(0, 15, len=7)

Agora vamos olhar os valores do objeto criado, em seguida elevar cada valor ao quadrado, atribuindo o resultado ao objeto “num2”. Em seguida tire a raiz-quadrada desse vetor.

num
length(num)
class(num)
num2 <- num^2
num2
sqrt(num2)
num

Agora vamos extrair apena o quinto elemento e em seguida substituir esse elemento pela palavra “quinto_elemento”. Em seguida vamos repetir as operações anteriores:

num[5]
num[5] <- "quinto_elemento"
num
num[-5]
 
length(num)
class(num)
num^2
sqrt(num^2)

O que aconteceu aqui? Por que não conseguimos mais operar o vetor “num”? Vamos agora voltar o vetor para sua forma original e operar novamente:

num[5] <- 10
num
num^2
sqrt(num^2)

Por que ainda não conseguimos? Vamos investigar o vetor e ajustá-lo.

length(num)
class(num)
num <- as.numeric(num)
sqrt(num^2)

Como já havíamos visto, uma das característica do vetor é que só armazena um tipo de natureza de dados e o R faz a coerção da classe do objeto dependendo da característica desses dados. Incluir algo que não é digito ou símbolo de decimal em um objeto da classe numérica faz com que a classe seja convertida automaticamente em character.

A raiz de um valor elevado ao quadrado é o próprio valor? O que aconteceria se o vetor fosse de números negativos? Veja a discussão sobre função quadrática e raiz quadrada como funções inversas nesse link

Leitura de Dados

A principal função para a leitura de dados no R é read.table. Ela é bem flexível e se aplica para a leitura de dados tabulares como uma planilha eletrônica usual, tendo colunas como variáveis e as linhas como observações. Antes da leitura de dados é importante garantir que temos eles bem organizados em uma planilha. O artigo Data Organization in Spreedsheets (Broman & Woo, 2018) faz uma boa síntese de boas práticas para estruturar dados brutos em uma planilha. Os exemplos de erros comuns em planilhas de ecologia do datacarpentry são ótimos, aposto que já cometeu alguns dos erros listados.

Tendo a planilha eletrônica com os dados brutos bem estruturados, precisamos exportá-la como arquivo texto puro para fazer a leitura no R. Os arquivos de texto são uma forma eficiente de armazenar dados que tem uma estrutura simples de linhas e colunas. Além de poderem ser abertos em qualquer programa simples de texto e sistema operacional, são reconhecidos nas planilhas eletrônicas como estrutura de dados. Normalmente usamos as extensões .txt ou .csv para designar arquivos de dados com campos separados por tabulação e vírgula, respectivamente1).

Quando exportar os dados deve ficar atento para algumas opções de exportação da planilha, as principais são os caracteres para designar a separação de campo e o símbolo de decimal. Evite, sempre que possível, caracteres especiais como acentos e aspas ( ' , `, ), se houver a opção de escolher a codificação de caracteres (“enconding”) opte pelo UTF-8.

Sabendo o formato que os dados foram salvos no arquivo texto, na maioria dos casos, precisamos apenas do seguintes argumentos para fazer a leitura dos dados no R 2):

Principais argumentos do read.table

Argumento Descrição Padrão Alternativas
file nome do arquivo 3)
 "nome_arquivo.txt"
"/caminho_dir/nome_arquivo.txt"
header nome das variáveis 4)
FALSE 
TRUE 
sep separador 5)
" " 
 ","    ";"    "\t"
dec símbolo de decimal
"." 
 "," 
as.is mantenha caracteres 6)
FALSE 
TRUE 

Verificando a leitura

Logo após a leitura dos dados é recomendável fazer a verificação do objeto lido para ter certificar que os dados foram lidos corretamente. É possível retornar na tela todo o objeto criado, mas para conjunto de dados grandes, fica difícil a visualização. Para isso, usamos algumas funções acessórias que extraem atributos ou parte dos dados. As principais são:

  • str: faz uma síntese da estrutura do objeto;
  • dim: mostra as dimensões do objeto, primeiro o número de linhas (observações) e em seguida colunas (variáveis);
  • head: mostra as primeiras linhas, por padrão as primeiras 6 observações;
  • names: mostra o nome das variáveis (colunas).

Dados de Caixeta

Entre na página levantamento de espécies em caixetais, leia a descrição dos dados e das variáveis e salve o arquivo de dados no diretório de trabalho.

Obs.: Se o arquivo abrir em uma aba do navegador, clique com o botão direito do mouse no link e selecione “salvar link” LOL.

Vamos fazer a leitura do arquivo com o padrão de leitura da função read.table e verificar em seguida a classe e a formatação do arquivo:

caixeta <- read.table(file = "caixeta.csv")

Esse código retornar o erro:

Error in scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  : 
  line 5 did not have 3 elements

Indicando que tentou ler o arquivo, mas algumas linhas tinham dimensão diferentes, ou seja, o formato não era tabular. Isso ocorre, normalmente devido ao tipo de separador de campo utilizado no arquivo que não é espaço, o padrão da função. No caso, o separador é , como relatado na documentação dos dados. Vamos usar o argumento sep para indicar o separador. Em seguida vamos verificar a classe do objeto.

caixeta <- read.table(file = "caixeta.csv", sep = ",")
class(caixeta)

Leitura de dados Online

A função read.table também funciona com endereço web como caminho para leitura de arquivos. Só precisamos fornecer a url do arquivo. No nosso caso, como os dados estão no nosso wiki, podemos usar:

caixeta <- read.table(file = "http://ecor.ib.usp.br/lib/exe/fetch.php?media=dados:caixeta.csv", sep = ",")

Data Frames

A classe do objeto é um data.frame. Esse é segundo tipo de objetos para armazenar dados no R que apresentamos: o vetor tem apenas uma dimensão de dados, o data.frame tem duas. Os datas frames no R são conjuntos de vetores de mesmo tamanho, similares a uma planilha de dados. Todas as características que vimos do objeto vetor, valem para as colunas do data.frame. Uma outra forma de pensar o data frame é que são variáveis (colunas) de um conjunto de observações (linhas). Assim como deve ser uma planilha de dados bem estruturada.

Uma sugestão importante, que evita muitos transtornos para quem está iniciando no R é: depois de efetuar a leitura sempre verificar a estrutura dos dados antes de iniciar as análises, usando as funções indicadas acima.

dim(caixeta)
names(caixeta)
str(caixeta)
head(caixeta)

Apesar de ter sido lido o objeto não parece o que deveria. A dimensão do objeto mostra que tem uma observação a mais, os nomes das variáveis não corresponde ao que está definido no metadado e as variáveis foram todas lidas com characters ou factor dependendo da versão do R. O head mostra exatamente o que aconteceu: a linha com os nomes das variáveis foi lida como sendo uma observação. Com isso, todas as variáveis foram classificadas como caracteres. Vamos agora usar o argumento header e fazer novamente a verificação:

caixeta <- read.table(file = "caixeta.csv", sep = ",", header = TRUE)
dim(caixeta)
names(caixeta)
str(caixeta)
head(caixeta)

No código acima temos resultados que podem variar dependendo da versão do R. Isso não é muito comum, pois a equipe de desenvolvedores busca manter a compatibilidade do scripts entre versões.

stringsAsFactors

Por padrão, até a versão anterior a 4.0.0 de abril de 2020, o padrão das funções read.table e data.frame era classificar as variáveis com caracteres como sendo um fator. Isso era definido com os padrões dos argumentos stringsAsFactors = TRUE ou as.is = FALSE. Desde da versão 4.0.0 o padrão é classificar as variáveis que contém caracteres como sendo character. Essa conversão automática para fator é um legado da linguagem S7).

Incluir Variáveis

Vamos então transformar as variáveis local e especie para fator, assim independente da versão do R instalada, estaremos todos com a mesma estrutura de objeto.

caixeta$local <- factor(caixeta$local)
caixeta$ssp <- factor(caixeta$especie)
str(caixeta)

Percebam que na primeira linha de comando estamos sobrescrevendo a variável local como fator para a mesma coluna. No caso da conversão de especie em fator, criamos uma nova variável no nosso data.frame chamada spp e preservamos a variável especie.

Incluir Variáveis no data.frame

Para incluir novas variáveis no data.frame só é preciso fornecer os valores e indicar a coluna onde esses valores devem ser atribuídos, tomando o cuidado de indicar um nome diferente das variável existentes caso não queira sobrescrever. O vetor da nova variável deve ter o mesmo tamanho do número de linhas do data.frame. A regra de ciclagem vale aqui também, veja o que acontece com o código:

caixeta$dap <- NA 
str(caixeta)

No quadro acima criamos uma variável chamada dap que contém só NAs (not available). Vamos incluir agora, nessa coluna, os valores de diâmetro à altura do peito. Para isso, vamos usar o valor de cap (circunferência à altura do peito) e a relação:

$$ dap = \frac{cap}{pi} $$

caixeta$dap <- caixeta$cap/pi 
str(caixeta)

Aqui também temos a regra da ciclagem com o valor da constante pi sendo ciclado para operar todos os elementos da variável cap.

Indexação

Acima usamos a indexação da coluna do data.frame pelo nome da variável, usando o operador $. Veja o que temos ao pedir a estrutura de uma variável do data.frame

str(caixeta$especie)
str(caixeta$cap)

O que temos é a estrutura básica de armazenamento de dados: vetores das classes básicas de dado. Portanto, para indexar as posições nesse vetores, podemos usar a indexação básica de vetores:

caixeta$dap[1]
caixeta$dap[c(1, 3, 5, 7, 9)]
caixeta$dap[seq(1, 19, by= 2)]

Uma outra forma de indexar é pelas posições da linha e coluna. No caso do data.frame isso é feito pela indicação das duas posições separadas por vírgula entre colchetes [ , ]. Sempre o valor antes da vírgula se refere a primeira dimensão do data.frame que são as linha (observações) e o valor depois refere-se a coluna (variável).

caixeta[1, 9]
caixeta[c(1, 3, 5, 7, 9), 9]
caixeta[seq(1, 19, by= 2), 9]

Por fim, é possível também combinar nomes das variáveis com as posições das observações:

caixeta[1, "dap"]
caixeta[c(1, 3, 5, 7, 9), "dap"]
caixeta[seq(1, 19, by= 2), "dap"]

Inclusive, combinar nomes de variáveis:

caixeta[1, c("dap", "cap")]
caixeta[c(1, 3, 5, 7, 9), c("dap", "cap")]
caixeta[seq(1, 19, by= 2), c("dap", "cap")]

Indexação com Lógica

Para apresentar essa última forma de indexação, vamos construir um data.frame sem fazer a leitura, usando a função data.frame que recebe os vetores de dados de mesmo tamanho.

trapalhoes <- data.frame(nomes = c("Didi","Dedé","Mussum","Zacarias"), ano.nasc = c(1936, 1936, 1941, 1934), vive = c("V", "V", "F", "F"))

Vamos agora calcular a idade dos meninos:

ano.atual <- as.numeric(format(Sys.Date(), "%Y"))
ano.atual - trapalhoes$ano.nasc 
trapalhoes$idade <- ano.atual - trapalhoes$ano.nasc 

Tá bom! Vou explicar a primeira linha de comando, ao mesmo tempo, indicar o caminho para entender comandos mais complicados em geral. Primeiro temos a característica da sintaxe aninhada, padrão do R. Para entender o que está sendo feito, pegue a função mais interna e veja o que ela está retornando, em seguida veja o que função externa a ela está fazendo com esse resultado, e assim por diante!

Sys.Date()
format(Sys.Date(), "%Y")
as.numeric(format(Sys.Date(), "%Y"))

Por que?

Pois bem, estamos primeiro pegando a data atual armazenada no computador, depois pegando apenas o ano e em seguida transformando o ano em número. Ué? Não seria mais fácil digitar o ano diretamente? Sim, mas depois teria que atualizar o código todos os anos antes do curso!

porquesim.gif

Para extrair informações específicas do data.frame usamos a indexação com um vetor lógico. Por exemplo, podemos nos perguntar: Quais os nomes dos trapalhões que nasceram antes de 1940?

antes40 <- trapalhoes$ano.nasc < 1940
antes40

O resultado desse teste lógico é um vetor de TRUE e FALSE:

[1]  TRUE  TRUE FALSE  TRUE

Ele nos diz que a condição é verdadeira para todas as posições menos para a terceira. Como o vetor lógico tem o mesmo comprimento do número de linhas, podemos então indexar o nosso data.frame com esse vetor, da seguinte forma:

trapalhoes[antes40, ]

ou diretamente, sem o objeto intermediário:

trapalhoes[trapalhoes$ano.nasc < 1940, ]

Note que fizemos a indexação pelas linhas, deixando a indexação da coluna vazia, ou seja, solicitando retornar todas as colunas para as linhas em que o vetor antes40 é TRUE. Como data.frame tem duas dimensões, a vírgula é mandatória para a indexação.

Nossa pergunta foi mais específica, perguntamos o nome e não pedimos as outras informações:

trapalhoes[antes40, "nomes" ]

Nesse caso, a indexação da coluna pode ser feita pelo nome da variável ou pela posição e também pode ser combinada.

E se quisermos o inverso, o nome e a idade dos que nasceram depois de 1940? Precisamos só inverter o vetor de TRUE e FALSE usando o operador !:

trapalhoes[!antes40, c("nomes","idade") ]

Essas são as principais lógicas de indexação no R. Aplicadas em um data.frame com quatro observações não parece muito vantajoso. Vamos nos perguntar algo então para os dados das caixeta que tem mais de mil observações:

Quais árvores, na amostra da Juréia, tem mais de 100 mm de dap?

jureiaVF <- caixeta$local == "jureia"
bigtree <- caixeta$dap > 100
caixeta[jureiaVF & bigtree, ]

Aqui utilizamos o indicador lógico & para perguntar para o R quais posições dos vetores jureiaVF e bigtree são verdadeiras em ambos os vetores.

E para saber quantas árvores tem na amostra da Juréia, quantas dessas são grandes e em que proporção? Lembra que o TRUE é operado algebricamente como sendo o valor 1?

sum(jureiaVF)
sum(bigtree & jureiaVF)
sum(bigtree & jureiaVF)/sum(jureiaVF)

Salvando Data Frame

Após manipular os dados no R podemos salvar uma nova versão em um arquivo texto. Para salvar a nossa nova versão dos dados de caixetais, que incorpora o dap, usamos a função write.table. Os parâmetros são parecidos a função de leitura, só que precisamos indicar qual o objeto deve ser salvo e nome do arquivo que será gravado. Caso queira salvar em um diretório diferente deve também fornecer o caminho das pastas do computador. Abaixo estamos salvando os dados no arquivo caixeta.txt, com os campos separados por tabulação (\t) e

write.table(caixeta, file = "dados/caixeta.txt", sep = "\t", dec = ",", row.names = FALSE)

Caso receba a mensagem de erro:

Error in file(file, ifelse(append, "a", "w")) : 
  cannot open the connection
In addition: Warning message:
In file(file, ifelse(append, "a", "w")) :
  cannot open file 'dados/caixeta.txt': No such file or directory

Significa que o caminho para gravar o arquivo tem algum problema, no caso não há a pasta dados subordinada ao seu diretório de trabalho. Para criar uma pasta pelo R, use o comando abaixo:

dir.create("dados")
dir.exists("dados")
dir()

Agora podemos rodar novamente a linha de comando do write.table e gravar o nosso arquivo caixeta.txt no diretório dados, subordinado ao diretório de trabalho que a sessão do R está associado.

Formato de Arquivo de Dados

Arquivos de dados no formato de texto são uma forma segura de salvar conjunto de dados pequenos ou medianos ( ~100 mil registros). Os formatos mais usados são os com campo separados por espaço (padrão do read.table), separado por vírgula ou ponto e vírgula, normalmente com extensão .csv, ou tabulação, normalmente com extensão .txt. A extensão é apenas uma indicação de formato e como é possível salvar o arquivo com qualquer extensão, precisamos saber qual estrutura foi utilizada para salvar os dados. O excel em sistemas operacionais em português salva arquivos csv separados por ;, com símbolo de decimal ,, o que causa bastante confusão. Nossa sugestão é que configure seu computador para decimal com . e estabeleça o seu padrão de separação de campo, deixando indicado em um arquivo acessório de metadados. Antes de ler um arquivo de dados de texto que desconheça a formatação, abra em um arquivo de edição de texto simples, como o bloco de notas, para verificar os símbolos de separação de campo e decimal.

Matrix e Array

Matrizes

Outro tipo de objeto no R com estrutura tabular é a matrix, que está associado à álgebra linear. A principal diferença com data.frame é que matrix só aceita uma classe de dados, assim como vector. A matrix é usada no sentido de matrizes da álgebra linear e operações matriciais.

Vamos aprender o objeto matrix associada ao estudo de dinâmica populacional.

Operações Matriciais

matrizestruturada.jpegAs matrizes de transição são uma maneira conveniente de modelar o crescimento de uma população dividida em faixas etárias, ou estágios de desenvolvimento 8). Uma forma de representar essas populações estruturadas9) é com diagramas mostrando as transições e permanências entre estados.

Uma forma compacta de representar matematicamente essas transições e permanência é utilizando a forma de matriz, que nesse caso se chama matriz de transição, como na figura abaixo: matrizestruturada1.jpeg

Uma população de Escobaria robbinsiorum (Cactaceae) no deserto do Arizona, com três estágios de desenvolvimento, tinha a seguinte a matriz de transição:

Escobaria robbinsiorum escRobbins.jpg

          0,43      0    0,56
          0,33    0,61     0
            0     0,30   0,96 

Os elementos da matriz, com exceção da fecundidade (F2 e F3 no diagrama), são as probabilidades de transição, num intervalo de tempo, do estágio correspondente ao número da coluna para o estágio correspondente ao número da linha. Por exemplo, a chance de um indivíduo passar do estágio 1 (plântula) para o 2 (jovem) é 0,33, e de permanecer em 1 é de 0,43. A fecundidade, representada nessa matriz como o elemento da primeira linha e terceira coluna (0,56) é o único que não é uma probabilidade e representa a contribuição, em número de jovens do estágio 1, que um adulto produz em média a cada ciclo.

Vamos criar um objeto da classe matriz com esses valores. Isso nos permitirá realizar operações matriciais para prever o tamanho da população.

matCory <- matrix( c(0.43, 0.33, 0, 0, 0.61, 0.3, 0.52, 0, 0.96), nrow = 3, ncol = 3)
matCory

A indexação da matrix é similar ao data.frame quando usamos o [. A indexação utilizando $ não se aplica nesse caso. Por exemplo, a fecundidade foi digitada errada no código acima e precisamos ajustá-la:

matCory[1, 3]
matCory[1, 3] <- 0.56
matCory

Aqui estamos usando uma regra básica dos objetos de dados no R: se consegue extrair um elemento de um objeto é possível atribuir algo a essa posição.

Agora crie um vetor com as abundâncias iniciais de indivíduos em cada classe. Vamos começar com uma população de 50 plântulas , 25 jovens e 10 adultos.

popN0 <- c(50, 25, 10)
popN0

Para calcular o número de indivíduos em cada estágio após um intervalo de tempo, basta multiplicar a matriz de transição pelas abundâncias dos indivíduos em cada estágio. Usamos o operador de multiplicação matricial %*% para isso. Qual será o número de plantas em cada estágio após três intervalos?

popN1 <- matCory %*% popN0
popN1
popN2 <- matCory %*% popN1
popN2
popN3 <- matCory %*% popN2
popN3

Vamos agora armazenar a trajetória do tamanho dos estágios na população em uma matrix:

pop <- matrix(c(popN0, popN1, popN2, popN3), ncol = 3, byrow = TRUE)
colnames(pop) <- c("plântula", "jovem", "adulto")
pop
pop <- rbind(pop, t(matCory %*% pop[nrow(pop),]))

No código acima, fazemos a multiplicação matricial %*% de duas matrizes: matCory e a última linha do objeto pop. Em seguida transpomos10) a matriz resultante com a função t para depois combinar o resultado transposto com o objeto pop. Para isso, usamos a função rbind que combina as linhas de dois objetos tabulares. Por último, sobrescrevemos o objeto pop com essa nova combinação.

Veja como as funções trabalham executando cada passo do mais interno para o mais externo:

nrow(pop)
pop[nrow(pop),]
matCory %*% pop[nrow(pop),]
t(matCory %*% pop[nrow(pop),])
rbind(pop, t(matCory %*% pop[nrow(pop),]))

Podemos fazer mais algumas multiplicações, guardando o resultado diretamente no objeto pop, usando somente a linha de comando novamente.

pop <- rbind(pop, t(matCory %*% pop[nrow(pop),]))
pop <- rbind(pop, t(matCory %*% pop[nrow(pop),]))
pop <- rbind(pop, t(matCory %*% pop[nrow(pop),]))
pop <- rbind(pop, t(matCory %*% pop[nrow(pop),]))
pop <- rbind(pop, t(matCory %*% pop[nrow(pop),]))
## ...

Vamos agora nomear essas linhas usando a função paste que combina caracteres.

rownames(pop) <- paste("t", seq(from = 0, to = (nrow(pop) - 1)), sep = "")

A função paste junta caracteres de dois vetores com os princípios da equivalência de posição e ciclagem, próprios das operações com vetores. Caso não tenha entendido o código acima, faça a separação de cada passo e veja a documentação das funções. Esse é um procedimento básico para entender códigos quando estamos iniciando no aprendizado de uma linguagem computacional.

Por fim, vamos olhar esses dados em um gráfico no objeto pop . O código abaixo vai ser abordado na aula de gráficos, por enquanto apenas copie e execute o código no R:

matplot(x = 0:(nrow(pop)-1), pop, type = "l", xlab = "Tempo", ylab = "Número de indivíduos", lty = 2, lwd = 2, col = c("red", "blue", "green"), cex.lab = 1.2, cex.axis = 1.2, las = 1)
legend("topleft", legend = colnames(pop), bty = "n", lty = 1, col = c("red", "blue", "green"))

Modelos Matriciais de Dinâmica Populacional

Com um pouco mais álgebra linear você pode obter muito mais informações sobre características da população biológica, apenas a partir das informações intrínsecas da matriz de transição (autovalores e autovetores). Por exemplo, a taxa de crescimento (λ) da população é o primeiro autovalor da matriz de transição, enquanto que o valor reprodutivo e a distribuição da proporção dos estágios no equilíbrio estão relacionados aos autovetores. Esses valores podem ser obtidos com a função eigen11). Para saber como calcular esses valores veja o roteiro da disciplina de ecologia de populações na qual esse tópico foi baseado.

eigen(matCory)

Matrix de comunidade

Um formato de dados clássico em ecologia de comunidades é o de espécies por localidade, como a ocorrência ou a contagem de indivíduos. Já usamos a função table para contagem de uma variável tipo fator. Vamos construir essa nova estrutura de dados a partir do objeto caixeta e fazer a coerção para a classe matrix.

str(caixeta)
caixTable <- table(caixeta$especie, caixeta$local)
str(caixTable)
class(caixTable)
caixTable[,"chauas"]
caixMatrix <- as.matrix(caixTable)
str(caixMatrix)
identical(caixMatrix, caixTable)
class(caixMatrix)

Apesar de parecer que a coerção do objeto table para matrix não tenha funcionado, a coerção funcionou como deveria. Os objetos da classe table são matrizes especiais de tabelas de contingência12) usadas para os testes de dependência entre variáveis categóricas. Para o R é um objeto subordinado à classe matrix.

Vamos agora fazer a manipulação desses dados para saber quantos indivíduos e espécies temos na localidade jureia. Primeiro precisamos manipular o objeto caixMatrix para que ela tenha apenas a informação de ocorrência

caixMatrix[caixTable > 0 ] <- 1
head(caixTable)
head(caixMatrix)

Agora podemos contar a coluna jureia em cada uma dos objetos:

sum(caixTable[, "jureia"])
sum(caixMatrix[, "jureia"])

Poderíamos usar a função apply para fazer a contagem de todas as colunas de uma vez. A função apply aplica uma função para alguma dimensão dos dados, no caso, coluna ou linhas, e cicla a função para todas as posições dessa dimensão.

apply(caixTable, MARGIN = 2, FUN = sum)
apply(caixMatrix, 2, sum)

Juntando Matrizes

É comum termos informações que estão em formato de dados tabulares e precisam ser agrupadas com outro conjunto de dados. Vamos olhar algumas das ferramentas para fazer isso.

Em construção

Combinando colunas ou linhas

As funções ``rbind`` e ´´cbind´´ são utilizada para concatenar dados pelas linhas ou colunas. Entretanto, só funcionam se a estrutura é a mesma, ou seja as variáveis são as mesmas e na mesma posição para acrescentar novas observações, ou as observações estão nas mesmas linhas para acrescentar novas variáveis.

trapa <- read.table("/home/aao/Ale2016/AleCursos/RUSP/R2020/Aulas/Aula3_dados/dados/trapa.csv", header = TRUE, sep = ",")
str(trapa)
trapa
 
trapaNome <- read.table("/home/aao/Ale2016/AleCursos/RUSP/R2020/Aulas/Aula3_dados/dados/trapa_nome.txt", header = TRUE, sep = ",")
str(trapaNome)
trapaNome
trapa
 
trapa$codinome == "Mussum" | trapa$codinome == "Dede"
trapa$codinome %in% c("Dede", "Mussum")
trapa$codinome %in% trapaNome$codinome
 
 
rbind(trapa, trapa)
trapabind <- cbind(trapa, trapaNome)
trapabind$vivo
names(trapabind)
trapabind$nascimento
trapabind[,7]
str(trapabind)
 
=== Merge ===
 
 
merge(trapa, trapaNome, by = "codinome")
trapa$codinome
trapaNome$codinome
 
merge(trapa, trapaNome, by = "codinome", all = TRUE)
trapa$codinome[2] <- trapaNome$codinome[3]
trapa$codinome
merge(trapa, trapaNome, by = "codinome")
 
=== match ===
 
 
(matchtrap <- match(trapa$codinome, trapaNome$codinome))
trapaNome[matchtrap, ]
trapa$nome <- trapaNome[matchtrap, "nome"]
trapa

Array

O objeto matrix por sua vez é apenas um objeto da classe array com apenas duas dimensões, assim como o vector é um array de uma dimensão. Veja a classe do objeto pop que criamos na sessão de multiplicação de matrizes:

class(pop)

A classe é matrix mas a classe parental é array. Essa possibilidade de um array ter muitas dimensões abre a possibilidade de efetuarmos operações e análises em múltiplas dimensões. As características e operações que fizemos em matrix se aplicam também para array.

Vamos avaliar um objeto dessa classe chamado Titanic. Primeiro vamos entender onde está esse objeto.

A função search mostra o caminho de busca nos compartimentos de memória da sessão do R. Nele há um pacote chamado datasets que é carregado por padrão ao abrirmos uma sessão do R.

search()
ls("package:datasets")
ls("package:datasets", pattern = "Tit")

Isso significa que esse objeto está disponível para uso sem a necessidade de carregá-lo. Vamos investiga alguns atributos dele:

is.array(Titanic)
dim(Titanic)
dimnames(Titanic)

Um tanto mais complicado de visualizar os dados do que uma planilha. Imagine os quatro níveis de Class como sendo as linhas de um planilha, sex como as colunas, age como sendo a repetição dessa estrutura para Child e Adult, por fim essa estrutura replicada para Survived igual a No e Yes. Como as quatro dimensões tem tamanhos pequenos é possível visualizar todos dados:

str(Titanic)
Titanic

Essa estrutura permite operar qualquer dimensão, ou mesmo algumas dimensões ao mesmo tempo. Vamos usar o apply para obter algumas informações interessantes sobre as vítimas do naufrágio.

Será que crianças e adultos tiveram a mesma proporção de vítimas?

apply(Titanic, c("Age", "Survived"), sum)

Será que a proporção de vítimas entre homens e mulheres foi similar?

apply(Titanic, c("Sex", "Survived"), sum)

E entre os passageiros de diferentes classes?

apply(Titanic, c("Class", "Survived"), sum)

Mistério do Titanic: mulheres e crianças primeiro

Os grupos com maior sobrevivência no desastre do Titanic foram as mulheres e crianças da primeira classe. Analisando dados de múltiplos acidentes marinhos o artigo ''Gender, social norms, and survival in maritime disasters'', Elinder & Erixson (2012) verifica que a distribuição de sobrevivência do Titanic é uma exceção. As evidências nos dados desse artigo mostram que a maior sobrevivência está entre os homens da tripulação e a menor entre as crianças.

Listas

Listas são os objetos mais versáteis para armazenar informação no R. Apesar de ter uma única dimensão, suas posições comportam qualquer outra classe de objeto que vimos até então. Normalmente os objetos mais complexos no R, como por exemplo resultados de modelos estatísticos, são casos especiais de listas padronizadas. Vamos criar a nossa primeira lista com alguns objetos desse tutorial:

minhaLista <- list(vectorNum = num, dfTrapa = trapalhoes, matPop = pop, arrayTit = Titanic) 
str(minhaLista)

A indexação da lista é um misto das classes de objetos que vimos anteriormente. Na sua primeira dimensão aceita tanto o nome com $ como um data.frame quanto um novo indexador que é o [[ colchete duplo.

minhaLista <- list(vectorNum = num, dfTrapa = trapalhoes, matPop = pop, arrayTit = Titanic) 
str(minhaLista)
minhaLista$dfTrapa
minhaLista[[3]]
minhaLista[["vectorNum"]]

Os elementos de cada posição podem ser acessados usando as indexações correspondentes a cada classe!

correpondentes
minhaLista$dfTrapa[, "nomes"]
minhaLista[[3]][1,]
minhaLista[["vectorNum"]] [7]

Lembre-se sempre de olhar o help. Não cometa o 7º pecado da lista do início desse tutorial, acostume-se com a documentação e como a sua estrutura. Toda as funções nesse tutorial são um link que leva à sua documentação.

Um Exemplo

No vídeo abaixo apresento um exemplo de manipulação de dados de um estudo sobre dinâmica de população de uma espécie de árvore (Guapira opposita) da floresta atlântica. Esse vídeo não é obrigatório!!

1)
existem muitos outros tipos de formatos de armazenamento de dados que incorporam dados mais complexos e georreferenciados
2)
read.table é muito flexível, veja a documentação!
3)
incluíndo a extensão e o caminho, caso não esteja no diretório de trabalho
4)
utiliza a primeira linha dos dados para o nome das colunas
5)
qual o símbolo separa os dados em uma linha. Ex: “\t” é tabulação
6)
O padrão até a versão 4.0 do R era transformar caracteres em fator na leitura. A partir dessa versão o padrão mudou e a versão mais recente da função não faz essa transformação automática.
7)
veja artigo sobre essa mudança em developer blog
9)
apresentam estágios diferentes
10)
ou seja, trocamos as linhas pelas colunas
11)
consulte a ajuda para interpretar o resultados dessa função
12)
tabelas de contagem
02_tutoriais/tutorial3/start.txt · Última modificação: 2020/09/23 11:44 por adalardo