Análise de Dados com o Software R:
Métodos Estatísticos, Computacionais e Econométricos

Prof. Adriano Azevedo Filho (azevedofilho@usp.br)

Operações algébricas e lógicas, data.frames e conversão de tipos

sumário geral | anterior | próximo

Conteúdo do Módulo

 1 - Leitura dos dados utilizado no módulo
     apagando informações do R com rm(list=ls()), read.csv2, file.choose

 2 - Operações algébricas elementares no contexto vetorial
     sum, length, ^, *, +, %*%, mean, sd, var, cat, variáveis auxiliares
    
 3 - Operações lógicas elementares no contexto vetorial
     ==, !=, <, <=, >, >=, &, |, !, variáveis auxiliares 
  
 4 - Extração de valores de variáveis (vetores) 

 5 - Extração de observações e variáveis de data.frames
     [], uso de vetores lógicos 

 6 - Criação de data.frames a partir de variáveis (vetores)
     data.frame, na.omit
    
 7 - Conversão de variáveis qualitativas (fator) para outros tipos (avançado)
     as.factor, as.numeric, as.character
  
 8 - Verificação e eliminação de NAs em variáveis e data.frames (avançado)
     is.na, na.omit, complete.cases  

1 - Lendo o arquivo “esalq2012mod.csv” de site na internet

Leia o arquivo “esalq2012mod.csv” que é o mesmo arquivo “esalq2012.csv”, com modificações nos nomes das variáveis e categorias visando torná-los mais compactos, cujos procedimentos estão descritos aqui.

É prudente, no início de uma nova análise, apagar toda a informação que esteja presente no sistema e que não será utilizada.

Mesmo desligando o R e ligando novamente pode ser que exista informação indesejável que não seja apagada e que pode interferir na análise. Isso reforça a importância do procedimento indicado a seguir, para “limpar” o ambiente de informações indesejadas, antes da leitura do novo data.frame.

No Windows essa “limpeza” também pode ser feita através de opção no menú do ambiente de desenvolvimento.

rm(list=ls())   ## apaga (quase tudo) antes de uma nova análise
alunos<-read.csv2("http://ihbs.com.br/html/esalq2012mod.csv")
dim(alunos)
## [1] 56 15
alunos[1:5,]
##   sex cur  ing ida cid rep pub pes alt tim sat rmat   pg  car      imc
## 1   m   e 2010  20 isp   1   0  57 172   t   2    s nsei nsei 19.26717
## 2   m   e 2010  20 isp   4   0  78 175   p   2    s nint priv 25.46939
## 3   f   e 2010  22 isp   2   5  59 170   s   2    s pgou priv 20.41522
## 4   m   e 2009  22 isp   6   0  78 179   o   2    s nint nsei 24.34381
## 5   m   e 2010  22 isp   3   4  80 180   t   5    s nsei priv 24.69136

Se o arquivo csv (BR) estiver no seu próprio computador, pode utilizar

caminho<-file.choose()       #seleção de arquivo via menus
alunos<-read.csv2(caminho)

2 - Operações algébricas elementares no contexto vetorial

O tópico explora operações algébricas envolvendo variáveis quantitativas do conjunto de dados (vetores) e variáveis auxiliares. Essas operações serão introduzidas na análise do peso dos indivíduos do data.frame “alunos” utilizando medidas estatísticas usuais de centralidade e dispersão.

Inicialmente vamos calcular a média, variância e desvio padrão do peso (variável alunos$pes), que é definido em kg. O R tem funções específicas para obtenção dessas medidas mas neste tópico vamos obtê-las a partir de operações algébricas mais fundamentais, até para aprender a utilizar essas operações em situações mais complexas.

Se representarmos a média, variância e desvio padrão do peso nesse conjunto de dados por \(\overline{\mbox{peso}}\),\(\mbox{var(peso)}\), e \(\mbox{dp(peso)}\), respectivamente, é usual a definição dessas medidas por: \[\overline{\mbox{peso}}=\frac{\sum_{i=1}^n\mbox{peso}_i}{n}\ \ \ \ \ \ \ \mbox{var(peso)}=\frac{\sum_{i=1}^n(\mbox{peso}_i-\overline{\mbox{peso}})^2}{n-1}\ \ \ \ \ \ \ \mbox{dp(peso)}=\sqrt{\mbox{var(peso)}}\] Nas fórmulas, \(\mbox{peso}_i\) representa o peso do indivíduo na observação \(i\) e \(n\) representa o número total de observações.

Inicialmente criaremos a variável auxiliar \(n\) para conter o número de observações e em seguida a variável \(m\) para armazenar a média:

n<-length(alunos$pes)  ## obtenção do número de observações
m<-sum(alunos$pes)/n   ## média pelas funções elementares
m                      ## observando o valor de m
## [1] 68.84286

A função “length” calcula o número de observações ou comprimento de uma variável (vetor); a função “sum”, por outro lado, soma todos os valores de uma variável quantitativa.

Para obtenção da variância e desvio padrão, vamos criar variáveis auxiliares, v e dp, e operacionalizar as fórmulas definidas anteriormente no R

v<-sum((alunos$pes-m)^2)/(n-1)
dp<-sqrt(v)
cat(v,dp)  ## mostrando os valores de v e sd calculados
## 220.2247 14.83997

Na primeira linha, inicialmente, o valor da média calculada (na variável m) é subtraída de todos os valores de peso correspondentes às observações disponíveis. O vetor resultante é elevado ao quadrado, algo que cria um vetor com todos os valores elevados ao quadrado. O vetor resultante é somado e dividido por \(n-1\), como requerido na fórmula da variância utilizada.

Alternativamente, a variância poderia ter sido calculada com o uso do operador %*%, que indica o produto escalar ou produto vetorial (as operações algébricas usuais, quando envolvidas por 2 % podem ter um significado especial, no contexto vetorial)

v<-(alunos$pes-m)%*%(alunos$pes-m)/(n-1)
v
##          [,1]
## [1,] 220.2247

Note que o resultado foi automáticamente convertido para formato matricial, numa matrix 1 x 1, que no caso é um escalar (simplesmente um número).

Os resultados apresentados poderiam ter sido obtidos mais diretamente pelas funções estatísticas do R:

cat(mean(alunos$pes),var(alunos$pes),sd(alunos$pes)) 
## 68.84286 220.2247 14.83997

3 - Operações lógicas elementares no contexto vetorial

O tópico introduz operações lógicas e valores lógicos no contexto da exploração de dados. É um tema que deve ser bem entendido em função de sua importância na análise de dados.

Algumas operações lógicas usuais: * == igual, != diferente * < menor, <= menor ou igual * > maior, >= maior ou igual * & “e” lógico * | “ou” lógico (barra vertical furada) * ! negação lógica

Prioridade das operações lógicas:

  • == != < <= > >= (mesma)
  • !
  • &
  • |

As operações são realizadas da esquerda para a direita. Na dúvida, use parentesis para forçar uma certa ordem na realização das operações.

Uma operação como

alunos$sex=='f'
##  [1] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE
## [12]  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [23]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE
## [34]  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE
## [45]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE
## [56] FALSE

resulta num vetor em que cada elemento, coincidente com a posição de cada observação, indica se é verdade (TRUE) ou falso (FALSE) o resultado lógico da operação realizada, indicando se o sexo do indivíduo é ‘f’, código que representa o sexo feminino.

Para contarmos o número de observações que atendem a essa condição, ou seja, o número total de mulheres ou frequência absoluta de mulheres, poderiamos usar

sum(alunos$sex=='f')
## [1] 22

Quando a função “sum” é aplicada a um vetor de valores lógicos, o valor TRUE é convertido em 1 e o valor FALSE é convertido em 0 (zero). Assim o resultado do uso do “sum”, nessa situação, resulta na soma das observações que atendem à condição estabelecida (ser mulher).

A frequência relativa de mulheres dentro do conjunto de alunos seria obtida por

sum(alunos$sex=='f')/length(alunos$sex)
## [1] 0.3928571

Algumas questões mais complexas:

  • Temos quantas mulheres com peso superior a 65 kg no conjunto de dados? Essa pergunta poderia ser respondida com o apoio do “e” lógico (&)
sum(alunos$sex=='f'&alunos$pes>65)
## [1] 4
  • Quantos alunos do conjunto de dados são “sofredores”? definidos como sendo torcedores do Corinthians (alunos$tim ==‘c’) ou que tenham tido alguma reprovação (alunos$rep>0):
sum(alunos$tim=='c' | alunos$rep>0)
## [1] 28

É importante entender que no “ou” lógico (|), somente quando as duas condições parciais são FALSE, o resultado será FALSE. Casos que atendem as 2 condições são contados como TRUE.

O operador ! inverte o valor lógico de uma observação. Um exemplo de sua aplicação é apresentado na resposta a pergunta: * Quantos alunos não torcem para o time Corinthians?

sum(!(alunos$tim=='c'))
## [1] 44

Exemplo mais detalhado - imc

No conjunto de dados, a variável imc indica o índice de massa corporal, uma medida biométrica que é usada para aferir como está o peso do indivíduo. Segundo a interpretação da OMS (Organização Mundial da Saúde, veja detalhes aqui) indivíduos com: * imc < 18,5 são muito magros * 18,5 <= imc <= 25 têm peso normal * 25 < imc <= 30 são considerados “gordinhos” ou com peso em excesso * imc > 30 são considerados obesos

Com base nesses critérios, responda:

  • Qual a proporção de alunos (frequência relativa) que está dentro da faixa de peso normal de peso, segundo os critérios do parágrafo anterior que usam o imc? obtenha essa proporção também para só para os homens e só para as mulheres do conjunto de dados.
sum(alunos$imc>=18.5 & alunos$imc <=25)/length(alunos$imc)  ## total
## [1] 0.75

Só nos homens

sum((alunos$imc>=18.5 & alunos$imc <=25)&alunos$sex=="m")/sum(alunos$sex=="m")  ## homens
## [1] 0.6470588

Só nas mulheres

sum((alunos$imc>=18.5 & alunos$imc <=25)&alunos$sex=="f")/sum(alunos$sex=="f")  ## mulheres
## [1] 0.9090909

4 - Extração de valores de variáveis (vetores)

Podemos extrair elementos de variáveis com facilidade através de vários procedimentos. Por exemplo, para extrair um vetor contendo o peso das observações 2,5 e 10, temos

alunos$pes[c(2,5,10)]
## [1] 78 80 62

para extrair as observações de 2 a 20, e colocar essas observações num vetor definido pela variável auxiliar \(x\), visualizando o conteúdo dessa variável em seguida, poderíamos usar

x<-alunos$pes[2:20]
x
##  [1] 78 59 78 80 66 85 54 63 62 59 56 80 60 66 73 73 98 69 65

A definição 2:20 cria automaticamente um vetor iniciando em 2 e terminando em 20.

Outra forma muito usual de extrair observações de variável ocorre pelo uso de um vetor de variáveis lógicas dentro da definição dos índices da variável de interesse. Serão extraídas todas as observações que coincidem com o valor TRUE no vetor (que deve ter o mesmo comprimento da variável original).

Com esse recurso poderíamos responder perguntas como * Qual é o peso médio só dos homens e só das mulheres do conjunto de dados?

pesohomens<-alunos$pes[alunos$sex=='m']
pesomulheres<-alunos$pes[alunos$sex=='f']
cat(mean(pesohomens),mean(pesomulheres)) ## médias
## 75.85882 58
cat(length(pesohomens), length(pesomulheres)) ## número de observações
## 34 22

5 - Extração de observações e variáveis de data.frames

Esse uso de vetores lógicos nos índices também é útil para extrair observações do data.frame que atendam algum condição específica. Por exemplo, para extrair todas as observações do data.frame, das colunas 1 a 5, correspondentes somente às mulheres, usaríamos

alunosmulheres<-alunos[alunos$sex=='f',1:5]  ## mulheres, colunas 1 a 5
alunosmulheres
##    sex cur  ing ida cid
## 3    f   e 2010  22 isp
## 8    f   e 2011  19 isp
## 10   f   e 2010  21 pir
## 11   f   e 2011  19 isp
## 12   f   e 2011  20 pir
## 14   f   e 2010  21 fsp
## 15   f   e 2011  20 isp
## 23   f   e 2011  19 pir
## 24   f   e 2010  22 csp
## 25   f   e 2011  19 csp
## 27   f   e 2010  20 isp
## 28   f   e 2011  21 isp
## 29   f   a 2010  20 isp
## 33   f   e 2011  19 pir
## 34   f   e 2011  22 isp
## 35   f   e 2004  27 pir
## 37   f   e 2011  20 fsp
## 38   f   e 2011  22 isp
## 41   f   e 2011  20 isp
## 45   f   e 2011  20 isp
## 51   f   a 2011  22 ext
## 52   f   e 2009  24 pir

Para extraírmos todas as colunas do data.frame, temos

alunosmulheres<-alunos[alunos$sex=='f',]  ## mulheres, todas as colunas
alunosmulheres
##    sex cur  ing ida cid rep pub  pes alt tim sat rmat   pg  car      imc
## 3    f   e 2010  22 isp   2   5 59.0 170   s   2    s pgou priv 20.41522
## 8    f   e 2011  19 isp   0   0 54.0 162   s   4    n nsei priv 20.57613
## 10   f   e 2010  21 pir   3   0 62.0 175   p   3    s nint priv 20.24490
## 11   f   e 2011  19 isp   0   3 59.0 164   c   3    n pgou priv 21.93635
## 12   f   e 2011  20 pir   0   0 56.0 165   n   4    n nint priv 20.56933
## 14   f   e 2010  21 fsp   1   0 60.0 170   o   3    n pgou empr 20.76125
## 15   f   e 2011  20 isp   0   0 66.0 170   t   4    n pgou priv 22.83737
## 23   f   e 2011  19 pir   0  11 52.5 162   c   4    n nsei priv 20.00457
## 24   f   e 2010  22 csp   0   0 62.0 163   c   3    n pgou nsei 23.33547
## 25   f   e 2011  19 csp   0   0 55.0 155   t   4    n nint priv 22.89282
## 27   f   e 2010  20 isp   0   0 41.0 162   t   4    n pgou priv 15.62262
## 28   f   e 2011  21 isp   0   3 46.0 154   t   4    n nint priv 19.39619
## 29   f   a 2010  20 isp   0   0 53.0 163   n   3    n nsei nsei 19.94806
## 33   f   e 2011  19 pir   0   1 52.0 165   p   3    n pgou empr 19.10009
## 34   f   e 2011  22 isp   0  11 52.0 160   p   4    n pgou priv 20.31250
## 35   f   e 2004  27 pir   0   4 62.0 172   n   4    n nsei priv 20.95727
## 37   f   e 2011  20 fsp   0  12 75.0 160   n   4    n pgou publ 29.29688
## 38   f   e 2011  22 isp   0  11 60.5 160   t   3    n pgou priv 23.63281
## 41   f   e 2011  20 isp   0  11 54.0 165   t   4    n pgea publ 19.83471
## 45   f   e 2011  20 isp   1  11 66.0 173   t   4    n nint priv 22.05219
## 51   f   a 2011  22 ext   0   0 75.0 180   n   5    n nsei priv 23.14815
## 52   f   e 2009  24 pir   4   0 54.0 165   t   5    s pgou priv 19.83471

Para selecionarmos colunas do data.frame, podemos usar diretamente o nome do data.frame seguido do nome da variável (separados por $), ou simplesmente,

alunos$sex  # é equivalente a
##  [1] m m f m m m m f m f f f m f f m m m m m m m f f f m f f f m m m f f f
## [36] m f f m m f m m m f m m m m m f f m m m m
## Levels: f m
alunos[,1]  # a coluna 1 é exatamente a coluna corresponente a variável sex
##  [1] m m f m m m m f m f f f m f f m m m m m m m f f f m f f f m m m f f f
## [36] m f f m m f m m m f m m m m m f f m m m m
## Levels: f m

a vírgula dentro do [,1], nessa posição, indica todas as observações. Poderiamos usar, para extrair as 5 primeiras observações

alunos[1:5,1]  # observações 1 a 5 da variável sex que está na posição 1
## [1] m m f m m
## Levels: f m

6 - Criação de data.frames a partir de variáveis (vetores)

x<-c(1,3,5,10.5)
y<-c("A","D2","X4","C")
z<-c(NA,20,34,50)
nomedodf<-data.frame(x,y,z)
nomedodf
##      x  y  z
## 1  1.0  A NA
## 2  3.0 D2 20
## 3  5.0 X4 34
## 4 10.5  C 50

Para remover observações que contenham 1 ou mais NAs, podemos utilizar a função “na.omit”

nomedodf<-na.omit(nomedodf)
nomedodf
##      x  y  z
## 2  3.0 D2 20
## 3  5.0 X4 34
## 4 10.5  C 50

7 - Conversão de variáveis qualitativas (fator) para outros tipos (avançado)

Quando uma variável definida por “strings” no arquivo externo que caracteriza um conjunto de dados é lido pelo comando read.csv2, esta é automaticamente entendida como sendo qualitativa (fator).

Há muitas possibilidades de conversão descritas a seguir.

Variável (vetor) tipo “character” em variável qualitativa (fator)

x<-c("nome1","nome2","nome3","nome1")
x
## [1] "nome1" "nome2" "nome3" "nome1"
x<-as.factor(x)
x
## [1] nome1 nome2 nome3 nome1
## Levels: nome1 nome2 nome3

Variável qualitativa (fator) em variável quantitativa tipo “numeric”

as.numeric(x)
## [1] 1 2 3 1

obs: os números correspondem a ordem das categorias na variável.

Variável quantitativa tipo “numeric” em variável qualitativa (fator)

x<-c(1,10,4,1)
x<-as.factor(x)
x
## [1] 1  10 4  1 
## Levels: 1 4 10

Variável qualitativa (fator) em tipo “character”

x<-as.character(x)  # x era um fator, veja o último comando
x
## [1] "1"  "10" "4"  "1"

8 - Verificação e eliminação de NAs em variáveis e data.frames (avançado)

Conjuntos de dados reais costumam ter muitos valores não definidos (ou faltantes). No R estes são representados pelo símbolo NA (devendo ser digitados com esse símbolo). Suponha que temos uma variável definida por

x<-c(NA,2,4,8,NA,1)  
x
## [1] NA  2  4  8 NA  1

Podemos verificar a existência de NAs utilizando a função is.na, que resultará em um vetor lógico com TRUE ocupando a mesma posição do NA na variável original.

is.na(x)  
## [1]  TRUE FALSE FALSE FALSE  TRUE FALSE

Para fazermos operações sobre vetores, eliminando os NAs, podemos proceder como no exemplo a seguir, em que a média só é calculada a partir dos valores numéricos do vetor

mean(x[!is.na(x)])  
## [1] 3.75

Em muitos comandos, há opções de como proceder quando há NAs nos dados, mas em alguns casos o próprio usuário deverá definir o que fazer nessa situação. A eliminação dos NAs é a medida mais drástica. Frequentemente há procedimentos mais elaborados.

Para eliminarmos todas as linhas de um data.frame que contenham 1 ou mais NAs, podemos utilizar a função “na.omit”, explicada no tópico 6, ou a função “complete.cases”.