| [[http://cmq.esalq.usp.br|{{:publico:tree-of-life.gif?100|CMQ: Centro de Métodos Quantitativos}}]] ^ **__Centro de Métodos Quantitativos__** \\ Departamento de Ciências Florestais \\ Escola Superior de Agricultura "Luiz de Queiroz" \\ **UNIVERSIDADE DE SÃO PAULO** | [[publico:tutoriais:uso-r:start|{{:publico:tutoriais:r-relampago:r-logo.png?90}}]] | ^ |
Curso Básico de R

para Mensuração Florestal:

Processamento de Dados

^ | | ^ Cubagem Rigorosa | | \\ ====== Objetivo ====== O objetivo desse curso é apresentar os procedimentos básicos necessários ao processamento de dados para realizar os cálculos de cubagem rigorosa do tronco de árvores pela técnica mais simples. Ao final desse curso você deverá ser capaz de: - saber o que são vetores no R, bem como os seus atributos básicos; - saber construir data frames a partir de diferentes vetores ou de leitura de dados externos; - conseguir executar as seguintes operações com data frames: * indexação, * agregação, * junção; - saber processar dados de secção de tronco para realizar os cálculos de cubagem rigorosa de um conjunto de árvores. ====== Vetores e seus Atributos ====== **VETORES** é um conjunto de observações do mesmo tipo de variável, isto é, de mesma escala. No R, podemos criar vetores na linha de comando utilizando a função **''c''**: x = c(10, 1, 3, 4, -5, 235) x a = c("maça", "peira", "mamão", "abacaxi") a Podemos criar uma sequência de números inteiros como o operador **'':''**: y = 1:10 y As colunas de um data frame funcionam como vetores. Vejamos um exemplo utilizando os dados do arquivo {{.:exemplo-caixeta.csv|exemplo-caixeta.csv}}: cax = read.csv("exemplo-caixeta.csv",head=TRUE) head(cax) cax$cap cax$local ==== Operações Matemáticas ==== Quando realizamos uma operação matemática sobre um vetor ela se aplica a cada elemento do vetor individualmente: 2*x y/3 log(y) sqrt(y) sin(x) x cax$cap / (10*pi) cax$h / 10 Podemos também realizar operações lógicas sobre os vetores: x < 0 x < 200 y > 5 ==== Classes de Vetores ==== Como em cada vetor todos os elementos são observações de uma mesma variável, para cada tipo de variável teremos uma classe de vetores: class(y) class(x) class(a) Também podemos ter vetores que contém as operações lógicas: op1 = x < 0 op1 class(op1) op2 = y > 5 op2 class(op2) Em resulo, as classes de vetores no R são: * **''integer''** : vetor de números inteiros; * **''numeric''** : vetor de números reais; * **''character''** : vetor de variáveis alfa-numéricas; * **''logical''** : vetor resultante de operações lógicas. É importante lembrar que as colunas de um data frame (variáveis), quando evocadas individualmente, são vetores com as suas respectivas classes. class(cax$arvore) class(cax$cap) class(cax$local) class(cax$especie) Mas por que as variáveis **''local''** e **''especie''** aparecem como **''factor''** e não como **''character''**? O R, sendo um ambiente para análise estatística de dados, assume que toda variável alfa-numérica terá uma função na modelagem estatística dos dados. Assim, ao ler um arquivo, ele transforma toda variável alfa-numérica na classe **''factor''**, que tem as propriedades estatísticas de um fator experimental. ==== Leitura de Arquivos CSV ==== Para o processamento dos dados, é geralmente mais fácil trabalharmos com a classe **''character''**, então para evitar que o R faça essa transformação automaticamente, utiliza-se o argumento **''as.is=TRUE''** na leitura dos dados. cax = read.csv("exemplo-caixeta.csv",head=TRUE,as.is=TRUE) class(cax$local) class(cax$especie) ==== Comprimento de Vetores ==== Outro atributo essencial de todo vetor é o seu comprimento (**''length''**): length(y) length(x) length(a) length(cax$cap) length(cax$arvore) length(cax$local) length(cax$especie) length(op1) length(op2) ====== A Estrutura dos Data Frames ====== Os data frames são tabelas de dados onde: * cada **linha** representa uma observação e * cada **coluna** representa uma variável medida na observação. No exemplo dos dados de caxeta: head(cax) cada linha (observação) representa um fuste de árvore medido no campo. A cada fuste foram "//associadas//" diversas variáveis. * As variáveis **''local''**, **''parcela''** , **''arvore''** e **''fuste''** são variáveis identificadoras, pois simplesmente identificam cada observação (fuste). * As variáveis **''cap''**, **''h''** e **''especie''** são as variáveis efetivamente "//medidas//" em cada fuste. Mas para compreendermos o processamento básico de dados no R devemos pensar os data frames de uma **outra** forma. Um data frame deve ser visto como uma junção de vetores que podem ter classes diferentes. Mas há dois aspectos essenciais nessa junção: * os vetores tem o mesmo comprimento, * os elementos dos vetores estão igualmente ordenados, segundo as observações que eles representam. Vejamos mais um exemplo de data frame a partir do arquivo {{.:exemplo-cubagem.csv|exemplo-cubagem.csv}}: cuba = read.csv("exemplo-cubagem.csv",header=T,as.is=T) head(cuba) O data frame **''cuba''** contem dados de cubagem de árvores de //Eucalyptus grandis// de diferentes regiões do Estado de São Paulo. Os seus vetores componentes devem ser entendidos como: * **''regiao''** - vetor que identifica a região de onde as árvores vieram, * **''arvore''** - vetor que identifica cada uma das árvores, * **''h_d''** - vetor das alturas ao longo do tronco onde os diâmetros das secções foram medidos, e * **''d_h''** - vetor dos diâmetros das secções nas respectivas alturas (**''h_d''**). Para evitar pontos decimais, a altura é apresentada em decímetros (//dm//) e o diâmetro em milímetros (//mm//). Note que nesse data frame as observações são as secções do tronco onde altura (**''h_d''**) e diâmetro (**''d_h''**) foram medidos. ===== Atributos dos Data Frames ===== Assim como os vetores que os compõem, os data frames também tem seus atributos. A classe de um data frame pode ser obtida da mesma forma que a classe dos vetores: class(cax) class(cuba) Naturalmente, a classe de um data frame é **''data.frame''**!! O tamanho de um data frame, no entanto, deve ser obtido de uma forma diferente dos vetores. Se tentarmos obter o **comprimento** de um data frame teremos: length(cuba) head(cuba) Note que o data frame **''cuba''** tem quatro vetores. Os data frame são **objetos bidimensionais**, isto é, possuem colunas (vetores) e linhas (observações). A função **''length''** simplesmente retorna o número de colunas do data frame. Para saber adequadamente o tamanho de um data frame devemos perguntar pelas suas **DIMENSÕES**: dim(cax) dim(cuba) prod(dim(cax)) Se quisermos saber o número total de elementos num data frame, basta multiplicarmos suas dimensões: prod(dim(cax)) prod(dim(cuba)) ====== Operações com Data Frames ====== No R, a organização dos dados em data frames é a forma mais apropriada tanto para o processamento básico dos dados quanto para análise e modelagem dos dados. Para se realizar o processamento de dados de modo eficiente é necessário se dominar algumas operações com os data frames. ===== Indexação de Data Frames ===== Chamamos de **INDEXAÇÃO** a operação de extrair linhas (observações) **e/ou** colunas (variáveis) de um data frame. O operador de indexação no R são os colchetes na seguinte forma: **''[ , ]''**. A vírgula dentro do colchetes separa a indexação de linhas da indexação de colunas. Vejamos alguns exemplos de indexação: # Indexação de LINHAS cax[ 10, ] # Retorna a décima observação do data frame cuba[ 182, ] # Retorna a observação 182 do data frame cax[ 10:23, ] # Retorna as observações 10 a 23 do data frame cuba[ c(18, 23, 26, 192, 200) , ] # Retorna a observação 182 do data frame # Indexação de LINHAS cax[ , 5] # Retorna a variável 5 ( **''cap''**) do data frame. cuba[ , 2 ] # Retorna a segunda variável (**''regiao''**) do data frame. cax[ , 5:6] # Retorna as variáveis 5 e 6 ( **''cap''** e **''h''**) do data frame. # Indexação de LINHAS E COLUNAS cax[ 1:5 , 5:6] # Retorna as observações 1 a 5 das variáveis 5 e 6 do data frame. cuba[ 107:112 , 3:4 ] # Retorna as observações 107 a 112 das variáveis 3 e 4 do data frame. Note que a indexação pode ser realizada por vetores. Os números não são a única forma de indexação no R. Há quatro tipos de **índices** no R. Cada um deles produz uma forma de indexação diferente: === Vetor de Número Inteiros Positivos === O R retorna os elementos correspondente aos números, sejam linhas ou colunas. Todos os exemplos acima são desse tipo. === Vetor de Número Inteiros Negativos === Nesse caso, o R **EXCLUI** os elementos correspondentes (linhas ou colunas) e retorna os dados sem elas: cuba[ -(12:219), ] cuba[ -(12:219), -1 ] cax[ -(15:198), -(1:4) ] cuba[ 1:5, -3] cax[ 1:5, -c(4, 7)] === Vetor "Character" === O vetor **''character''** funciona como **NOME** dos elementos (linhas ou colunas). Esse tipo de indexação é mais comumente utilizado com as colunas, uma vez que as variáveis sempre terão seus nomes: colnames(cax) # Nomes das colunas (variáveis) cax[ 1:5, "cap"] cax[ 1:5, c("cap","h")] colnames(cuba) # Nomes das colunas (variáveis) cuba[ 1:5 , "h_d" ] cuba[ 1:5 , c("regiao","d_h") ] Note que o **valor** de uma variável caracter devem ser **sempre** apresentado dentro de aspas duplas (**"**). Embora menos comum, essa forma de indexação também pode ser utilizado para seleção de observações (linhas): rownames(cuba) # Nomes das linhas (observações) cuba2 = cuba[ 1:10, 3:4] rownames(cuba2) paste( "posicao", 1:10 ) # Cola a palavra "posicao" aos números de 1 a 10 rownames(cuba2) = paste( "posicao", 1:10 ) cuba2 cuba2[ "posicao 7", ] cuba2[ paste("posicao", 5:9), ] === Vetor Lógico === Quando um vetor lógico é utilizado como índice, o R retorna aquele elementos correspondentes ao valor **''TRUE''** do vetor lógico. cax$dap = cax$cap / (pi * 10) cax$ht = cax$h / 10 cax[ cax$dap < 5 , ] cax[ cax$dap >= 10 & cax$dap <= 10.5 , ] cax[ cax$ht < 3, ] cax[ cax$ht > 17, ] cax[ cax$local == "jureia" & cax$dap < 8, ] cax[ cax$local == "chauas" & cax$dap > 18, ] A tabela abaixo apresenta os símbolos utilizados nas operações lógicas: ^ Símbolo ^ Operação ^ | ''=='' | Igualdade | | ''>'' | Maior | | ''<'' | Menor | | ''>='' | Maior ou igual | | ''<='' | Menor ou igual | | ''!'' | Negação | | ''!='' | Não igual, i.e., diferente | | ''&'' | **E** para junção de duas operações lógicas | | ''|'' | **OU** para junção de duas operações lógicas | === Exercício === Constura dois data frames a partir do data frame **''cuba''** : * Um data frame contendo a variável **''arvore''** mas apenas com o DAP das árvores. * Um data frame contendo a variável **''arvore''** mas apenas com a altura total das árvores ===== Agregação de Dados em Data Frames ===== O termo **AGREGAÇÃO** é empregado para definir a operação de aplicar uma operação matemática num conjunto de dados num nível **MAIS** detalhado para obter os resultados num nível **MENOS** detalhado. Por exemplo, no conjunto de dados dos caixetais, deseja-se saber a área basal das parcelas. Esse resultado é obtido numa sequência de passos: (1) Calcular a área transversal de cada fuste((Nota: os dados dos caixetais estão no nível de fuste e não de árvore)). cax$g = (pi/4) * (cax$dap/100)^2 (2) As áreas transversais dos fustes devem ser somadas para cada parcela, ou seja, * devemos **agregar** os dados de área transversal **do nível** de fuste (= //variável a ser agregada//) * **para o nível** de parcela (= //variável índice ou de agregação//) * **somando** (= //função ou operação de agregação//). Esses três elementos compõem os argumentos da função **''aggregate''** utilizada na operação: cax.parc = aggregate(x = cax$g, by = list(cax$parcela), FUN=sum) head(cax.parc) colnames(cax.parc) = c("parcela","g") # nomeia as variáveis head(cax.parc) # G em m2 cax.parc$g = cax.parc$g * 10000/200 # as parcelas são de 200 m2 head(cax.parc) # G em m2/ha A função de agregação pode ser definida dentro do comando para facilitar os cálculos: cax.parc = aggregate(x = cax$g, by = list(cax$parcela), FUN= function(x){sum(x)*10000/200} ) colnames(cax.parc) = c("parcela","g") # nomeia as variáveis head(cax.parc) # G em m2/ha A agregação pode ser realizada utilizando mais de uma variável de agregação. Por exemplo, deseja-se calcular a densidade das espécies dos caixetais por local: cax.den = aggregate(x = cax$arvore, by = list(cax$especie, cax$local), FUN= function(x){length(unique(x))*10000/200} ) colnames(cax.den) = c("especie","local","den") # nomeia as variáveis cax.den # densidade em 1/ha === Exercício === Utilizando a equação de volume abaixo, encontre o volume para cada parcela dos caixetais em metros cúbicos por hectare. **''v = -0.4448 + 0.0320 * (dap^2) * ht''** * **''v''** em //dm3//, * **''dap''** em //cm//, e * **''ht''** em //m//. === Exercício === Encontre a dominância das espécies dos caixetais para cada local. ===== Junção de Data Frames ===== A junção de data frames pode ser realizada de duas formas: * alinhando-se as variáveis (colunas) correspondentes, ou * alinhando-se as observações (linhas) correspondentes. Na junção de data frames pelas variáveis, os data frames devem ter exatamente as mesmas variáveis. Vejamos um exemplo. Primeiramente vamos separar as observações de um data frame: cha = cax[ cax$local == "chauas", ] jur = cax[ cax$local == "jureia", ] ret = cax[ cax$local == "retiro", ] head(cha) head(jur) head(ret) Agora, podemos juntar esses data frames utilizando a função **''rbind''**: cax.jun = rbind(cha, jur, ret) dim(char) dim(jur) dim(ret) dim(cax.jun) dim(cax) Na segunda forma de junção, as variáveis diferentes são juntadas segundo as observações correspondentes. Exemplo: caixetais. Deseja-se obter as seguintes informações por espécie: * DAP e altura médios, * DAP mínimo e máximo, e * número de fustes. dh.m = aggregate(cax[, c("dap","ht")], list(cax$especie), mean) colnames(dh.m) = c("especie","mdap","mht") head(dh.m) d.min = aggregate(cax$dap, list(cax$especie), min) colnames(d.min) = c("especie","dap.min") d.max = aggregate(cax$dap, list(cax$especie), max) colnames(d.max) = c("especie","dap.max") d.nf = aggregate(cax$dap, list(cax$especie), length) colnames(d.nf) = c("especie","nfuste") cax.sp = merge(dh.m, d.min) head(cax.sp) cax.sp = merge(cax.sp, d.max) head(cax.sp) cax.sp = merge(cax.sp, d.nf) head(cax.sp) === Exercício === Utilizando os dados dos caixetais, construa um data frame com as seguintes informações por parcela: * área basal * volume * número de fustes === Exercício === Utilizando os dados dos caixetais, construa um data frame com as seguintes informações por local: * número de espécies (riqueza), * índice de diversidade de shannon, * número de espécies raras (= espécies com somente um fuste na amostra), e * proporção de espécies raras. ====== Procedimentos para Cubagem Rigorosa ====== Os procedimentos apresentados constiuem a base para o processamento de dados no R. Tais procedimentos são suficientes para se realizar os cálculos de cubagem rigorosa de árvores, quando as medições da secção do tronco são realizadas com intervalo constante. Vejamos os passos necessários para a cubagem rigorosa do **volume total** do tronco: ==== (1) Colocar as Variáveis em Unidades Convenientes ==== Utilizaremos os dados do data frame **''cuba''**. Coloquemos os dados de diâmetro e altura em unidades convenientes: head(cuba) cuba$hd = cuba$h_d / 10 # altura de dm para m cuba$dh = cuba$d_h / 10 # diametro de mm para cm head(cuba) ==== (2) Separação da Informação da Ponta do Tronco ==== Note que a última secção tem diâmetro zero, logo a altura dessa secção é a altura total da árvore. cuba[ cuba$arvore == 1, ] Essa secção deve ser separada, pois a ponta do tronco será cubada de forma diferente das demais seções: cuba.toras = cuba[ cuba$dh != 0, ] cuba.toras[ cuba.toras$arvore == 1, ] cuba.ponta = aggregate(cuba.toras[ , c("hd","dh")], list(regiao=cuba.toras$regiao, arvore=cuba.toras$arvore), function(x) x[length(x)] ) cuba.ponta ==== (3) Separação das Informação de DAP e Altura Total ==== Primeiro, separaremos o DAP: cuba.d = cuba[ cuba$hd == 1.3, c("regiao","arvore","dh")] colnames(cuba.d)[3] = "dap" head(cuba.d) Segundo, a altura total cuba.h = cuba[ cuba$dh == 0, c("regiao","arvore","hd")] colnames(cuba.h)[3] = "ht" head(cuba.h) Terceiro, se junta os dados: cuba.dh = merge(cuba.d, cuba.h) head(cuba.dh) cuba.dh = merge(cuba.dh, cuba.ponta) head(cuba.dh) rm(cuba.d, cuba.h, cuba.ponta) # Limpando a área ==== (4) Cubagem Rigorosa das Toras por Smalian ==== Primeiro é necessário definir uma função para realizar a cubagem rigorosa por Smalian para toras de mesmo comprimento. A função abaixo realiza a cubagem rigorosa para o tronco inteiro (exceto a ponta) numa única expressão matemática que depende do diâmetro das secções (argumento **''x''**) e do comprimento constante da tora (argumento **''l''**): smalian.cr = function(x, l) { l*(pi/8)*sum( x[c(1,length(x))]^2, 2*x[-c(1,length(x))]^2) } Para realizar a cubagem basta aplicá-la na agregação dos dados de toras: cuba.vol1 = aggregate(cuba.toras$dh/100, list(cuba.toras$regiao, cuba.toras$arvore), smalian.cr, l=1) colnames(cuba.vol1) = c("regiao","arvore","volume") cuba.vol1 Podemos agora juntar os dados de volume com os demais dados das árvores: cuba.v = merge(cuba.dh, cuba.vol1) cuba.v ==== (5) Volume Total das Árvores ==== Assumindo que as pontas tem volume de um cone, podemos calcular esse último volume por árvore: cuba.v$vp = (1/3) * (pi/4) * (cuba.v$dh/100)^2 * (cuba.v$ht - cuba.v$hd) cuba.v Assim podemos obter o volume total de cada árvore: cuba.v$voltot = cuba.v$volume + cuba.v$vp cuba.v Concluímos a operação, mantendo apenas as variáveis de interesse: cuba.arv = cuba.v[ , c("regiao","arvore","dap","ht","voltot")] cuba.arv plot( voltot ~ I(dap^2*ht), data = cuba.arv) === Exercício === Repita a operação de cubagem rigorosa com os dados do arquivo {{.:exemplo-cubagem-2.csv|exemplo-cubagem-2.csv}}. Encontre: * o volume total **com** casca e * o volume total **sem** casca. \\ \\ ====== Autor ====== João Luís Ferreira Batista Laboratório de Biometria Ecológica
Centro de Métodos Quantitativos
Departamento de Ciências Florestais
Escola Superior de Agricultura "Luiz de Queiroz"
UNIVERSIDADE DE SÃO PAULO