11 Checagem dos dados

No tutorial abaixo vamos usar dados de avistamento de aves em fisionomias de cerrado. Baixem o arquivo contendo esses dados (https://github.com/LABOTAM/LABOTAM.github.io/blob/main/dados/aves_cerrado.csv) para a sua pasta de trabalho.

Vamos praticar neste tutorial o uso de funções que nos mostram a estrutura e resumo dos dados. Já vimos como utilizar essas funções na parte I deste livro.

  • str() - mostra a estrutura do objeto dos dados;
  • head() e tail()- mostra a cabeça ou a cauda da sua tabela de dados, respectivamente;
  • summary() - faz um resumo de todas as variáveis nos seus dados.

Vamos começar importando os dados ao R:

## Lendo a planilha com read.table
avesc <- read.table("aves_cerrado.csv", row.names = 1, header = T, sep = ";", dec = ",", as.is = T, na.strings = c("NA", "", "NULL"))

Repare no argumento na.strings da função read.table(). Ele é importante na importação de dados pois garante a codificação de valores ausentes usando a constante lógica NA do R. Se você não definir isso, o padrão é reconhecer apenas células que tenham o texto NA como valor faltante. Veja também o uso do argumento as.is = TRUE, que indica que não se deve converter colunas de texto em fatores (ou você pode usar o argumento stringsAsFactors para isso; este mesmo argumento é utilizado também na função data.frame()). Vamos ver as primeiras 10 linhas do objeto avesc:

head(avesc, 10)
fisionomia urubu carcara seriema
Ce1 Ce 5 18 6
Ce2 Ce 7 7 6
Ce3 Ce 5 14 4
Ce4 Ce 3 12 5
Ce5 Ce 4 16 4
Ce6 Ce NA 20 NA
Ce7 Ce 6 19 4
Ce8 Ce 4 21 10
Ce9 Ce 2 11 6
Ce10 Ce 5 9 7

Vamos criar uma cópia para usarmos depois.

aves2 <- avesc

É sempre bom verificar se os dados foram importados corretamente. É sempre um bom procedimento checarmos as dimensões do objeto com a função dim(), primeiras e últimas linhas e colunas do objeto com funções head() e tail() respectivamente

dim(avesc) # a dimensao do objeto (linhas e colunas)
## [1] 60  4
head(avesc, 3) # a cabeca do objeto (tres primeiras linhas)
fisionomia urubu carcara seriema
Ce1 Ce 5 18 6
Ce2 Ce 7 7 6
Ce3 Ce 5 14 4
tail(avesc, 3) # a cauda do objeto (tres ultimas linhas)
fisionomia urubu carcara seriema
CL18 CL 12 6 7
CL19 CL 18 5 4
CL20 CL 19 4 4
avesc[nrow(avesc), ] # ultima linha
fisionomia urubu carcara seriema
CL20 CL 19 4 4

Parece que está tudo certo! Vamos checar a estrutura do objeto:

# mostra a estrutura do data.frame
str(avesc)
## 'data.frame':    60 obs. of  4 variables:
##  $ fisionomia: chr  "Ce" "Ce" "Ce" "Ce" ...
##  $ urubu     : int  5 7 5 3 4 NA 6 4 2 5 ...
##  $ carcara   : int  18 7 14 12 16 20 19 21 11 9 ...
##  $ seriema   : int  6 6 4 5 4 NA 4 10 6 7 ...

Reparem que há uma variável de texto (chr) e três variáveis de números inteiros (int). Próximo passo é sempre checar um sumário estatístico das variáveis presentes no objeto usando a função summary():

# mostra um resumo da variacao nas colunas
summary(avesc)
fisionomia urubu carcara seriema
Length:60 Min. : 2.00 Min. : 3.00 Min. : 2.000
Class :character 1st Qu.: 7.00 1st Qu.: 5.50 1st Qu.: 4.000
Mode :character Median :12.00 Median : 9.00 Median : 5.000
NA Mean :11.93 Mean :10.25 Mean : 5.345
NA 3rd Qu.:16.50 3rd Qu.:14.00 3rd Qu.: 6.000
NA Max. :22.00 Max. :24.00 Max. :12.000
NA NA’s :1 NA’s :1 NA’s :2

Há indicação de presença de valores NA nas variáveis numéricas, que são valores faltantes.

11.1 Tem valores ausentes?

Há valores ausentes em nossos dados? Eles são mesmo faltantes? Ou seja, o que significam valores ausentes no seu conjunto de dados?

Podemos utilizar a função is.na() para encontrar a constante lógica NA, ou seja, a constante que indica valores ausentes (reveja o uso da função is.na() na seção 2.6.3). Vejam o ? da constante lógica NA para entender o significado dela no R:

?NA

Continuemos de onde paramos na seção anterior. Vimos que há a presença de NA no data.frame avesc. Chequemos quais registros (linhas) têm valores NA. Vamos checar primeiramanete a variável avesc$urubu:

avesc$urubu == NA ## erro: não retorna verdadeiro ou falso
avesc[avesc$urubu == NA, ] ## também não funciona

Reparem que os comandos acima, apesar de funcionarem, não respondem à nossa pergunta que é saber quais linhas possuem NA. Para isso, devemos nos valer da função is.na():

is.na(avesc) # pergunta em todo o data frame: quem é NA?
fisionomia urubu carcara seriema
Ce1 FALSE FALSE FALSE FALSE
Ce2 FALSE FALSE FALSE FALSE
Ce3 FALSE FALSE FALSE FALSE
Ce4 FALSE FALSE FALSE FALSE
Ce5 FALSE FALSE FALSE FALSE
Ce6 FALSE TRUE FALSE TRUE
Ce7 FALSE FALSE FALSE FALSE
Ce8 FALSE FALSE FALSE FALSE
Ce9 FALSE FALSE FALSE FALSE
Ce10 FALSE FALSE FALSE FALSE
Ce11 FALSE FALSE FALSE FALSE
Ce12 FALSE FALSE FALSE FALSE
Ce13 FALSE FALSE FALSE FALSE
Ce14 FALSE FALSE FALSE FALSE
Ce15 FALSE FALSE FALSE FALSE
Ce16 FALSE FALSE FALSE FALSE
Ce17 FALSE FALSE FALSE FALSE
Ce18 FALSE FALSE FALSE FALSE
Ce19 FALSE FALSE FALSE FALSE
Ce20 FALSE FALSE FALSE FALSE
CC1 FALSE FALSE FALSE FALSE
CC2 FALSE FALSE FALSE FALSE
CC3 FALSE FALSE FALSE FALSE
CC4 FALSE FALSE FALSE FALSE
CC5 FALSE FALSE FALSE TRUE
CC6 FALSE FALSE FALSE FALSE
CC7 FALSE FALSE FALSE FALSE
CC8 FALSE FALSE FALSE FALSE
CC9 FALSE FALSE FALSE FALSE
CC10 FALSE FALSE FALSE FALSE
CC11 FALSE FALSE FALSE FALSE
CC12 FALSE FALSE FALSE FALSE
CC13 FALSE FALSE FALSE FALSE
CC14 FALSE FALSE FALSE FALSE
CC15 FALSE FALSE FALSE FALSE
CC16 FALSE FALSE FALSE FALSE
CC17 FALSE FALSE FALSE FALSE
CC18 FALSE FALSE FALSE FALSE
CC19 FALSE FALSE FALSE FALSE
CC20 FALSE FALSE FALSE FALSE
CL1 FALSE FALSE FALSE FALSE
CL2 FALSE FALSE FALSE FALSE
CL3 FALSE FALSE FALSE FALSE
CL4 FALSE FALSE FALSE FALSE
CL5 FALSE FALSE FALSE FALSE
CL6 FALSE FALSE FALSE FALSE
CL7 FALSE FALSE FALSE FALSE
CL8 FALSE FALSE FALSE FALSE
CL9 FALSE FALSE TRUE FALSE
CL10 FALSE FALSE FALSE FALSE
CL11 FALSE FALSE FALSE FALSE
CL12 FALSE FALSE FALSE FALSE
CL13 FALSE FALSE FALSE FALSE
CL14 FALSE FALSE FALSE FALSE
CL15 FALSE FALSE FALSE FALSE
CL16 FALSE FALSE FALSE FALSE
CL17 FALSE FALSE FALSE FALSE
CL18 FALSE FALSE FALSE FALSE
CL19 FALSE FALSE FALSE FALSE
CL20 FALSE FALSE FALSE FALSE
!is.na(avesc) # inverte: quem não é NA?
fisionomia urubu carcara seriema
Ce1 TRUE TRUE TRUE TRUE
Ce2 TRUE TRUE TRUE TRUE
Ce3 TRUE TRUE TRUE TRUE
Ce4 TRUE TRUE TRUE TRUE
Ce5 TRUE TRUE TRUE TRUE
Ce6 TRUE FALSE TRUE FALSE
Ce7 TRUE TRUE TRUE TRUE
Ce8 TRUE TRUE TRUE TRUE
Ce9 TRUE TRUE TRUE TRUE
Ce10 TRUE TRUE TRUE TRUE
Ce11 TRUE TRUE TRUE TRUE
Ce12 TRUE TRUE TRUE TRUE
Ce13 TRUE TRUE TRUE TRUE
Ce14 TRUE TRUE TRUE TRUE
Ce15 TRUE TRUE TRUE TRUE
Ce16 TRUE TRUE TRUE TRUE
Ce17 TRUE TRUE TRUE TRUE
Ce18 TRUE TRUE TRUE TRUE
Ce19 TRUE TRUE TRUE TRUE
Ce20 TRUE TRUE TRUE TRUE
CC1 TRUE TRUE TRUE TRUE
CC2 TRUE TRUE TRUE TRUE
CC3 TRUE TRUE TRUE TRUE
CC4 TRUE TRUE TRUE TRUE
CC5 TRUE TRUE TRUE FALSE
CC6 TRUE TRUE TRUE TRUE
CC7 TRUE TRUE TRUE TRUE
CC8 TRUE TRUE TRUE TRUE
CC9 TRUE TRUE TRUE TRUE
CC10 TRUE TRUE TRUE TRUE
CC11 TRUE TRUE TRUE TRUE
CC12 TRUE TRUE TRUE TRUE
CC13 TRUE TRUE TRUE TRUE
CC14 TRUE TRUE TRUE TRUE
CC15 TRUE TRUE TRUE TRUE
CC16 TRUE TRUE TRUE TRUE
CC17 TRUE TRUE TRUE TRUE
CC18 TRUE TRUE TRUE TRUE
CC19 TRUE TRUE TRUE TRUE
CC20 TRUE TRUE TRUE TRUE
CL1 TRUE TRUE TRUE TRUE
CL2 TRUE TRUE TRUE TRUE
CL3 TRUE TRUE TRUE TRUE
CL4 TRUE TRUE TRUE TRUE
CL5 TRUE TRUE TRUE TRUE
CL6 TRUE TRUE TRUE TRUE
CL7 TRUE TRUE TRUE TRUE
CL8 TRUE TRUE TRUE TRUE
CL9 TRUE TRUE FALSE TRUE
CL10 TRUE TRUE TRUE TRUE
CL11 TRUE TRUE TRUE TRUE
CL12 TRUE TRUE TRUE TRUE
CL13 TRUE TRUE TRUE TRUE
CL14 TRUE TRUE TRUE TRUE
CL15 TRUE TRUE TRUE TRUE
CL16 TRUE TRUE TRUE TRUE
CL17 TRUE TRUE TRUE TRUE
CL18 TRUE TRUE TRUE TRUE
CL19 TRUE TRUE TRUE TRUE
CL20 TRUE TRUE TRUE TRUE
avesc[!is.na(avesc)]
##   [1] "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce"
##  [16] "Ce" "Ce" "ce" "Ce" "Ce" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC"
##  [31] "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CL" "CL" "CL" "CL" "CL"
##  [46] "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL"
##  [61] " 5" " 7" " 5" " 3" " 4" " 6" " 4" " 2" " 5" " 6" " 6" " 7" " 6" " 5" " 5"
##  [76] " 3" "13" " 8" " 7" "22" "10" "17" "16" "20" "18" "16" "14" "12" "15" " 9"
##  [91] "11" "20" "18" " 8" "15" "17" "17" "12" "12" "11" "10" "19" "15" "13" "12"
## [106] "16" "13" "19" "19" "11" "18" "15" "19" "13" "16" "10" "12" "18" "19" "18"
## [121] " 7" "14" "12" "16" "20" "19" "21" "11" " 9" "12" "24" "17" "16" "15" "12"
## [136] "14" "14" "21" "13" " 8" "16" "14" "16" "10" " 7" " 8" " 8" " 7" "14" "11"
## [151] "12" "11" "11" " 7" "14" " 8" "14" " 7" " 9" " 3" " 5" " 5" " 8" " 6" " 5"
## [166] " 5" " 3" " 5" " 3" " 3" " 6" " 4" " 4" " 5" " 3" " 6" " 5" " 4" " 6" " 6"
## [181] " 4" " 5" " 4" " 4" "10" " 6" " 7" " 8" " 5" " 6" " 4" " 6" " 8" " 3" " 4"
## [196] " 2" " 4" " 5" " 3" " 3" " 6" " 3" " 5" " 4" " 4" " 4" " 8" " 4" " 4" " 3"
## [211] " 6" " 5" " 5" " 6" " 6" "12" " 9" " 6" " 5" " 4" " 6" " 4" " 5" " 6" " 5"
## [226] " 4" " 9" " 7" " 5" " 4" " 6" " 2" "10" " 7" " 4" " 4"

Proceder com o último comando gera um resultado confuso, pois o data.frame é convertido em um vetor de dimensão de 236 valores. Podemos investigar da maneira abaixo. Checamos qual é o tamanho total de valores presentes no objeto avesc, multiplicando o número de linhas pelo número de colunas através da expressão (nrow(avesc) * ncol(avesc)). Temos então um número total de 240 valores possíveis em avesc. E comparamos essa valor com o número de valores não faltantes em avesc através da expressão length(avesc[!is.na(avesc)]), que retorna 236. Portanto, se não houver valores faltantes, a primeira expressão abaixo deve retornar verdadeiro (TRUE), e falso (FALSE) se houver valores faltantes:

(nrow(avesc) * ncol(avesc)) == length(avesc[!is.na(avesc)])
## [1] FALSE

Então quantos valores faltantes existem em nossos dados?

# ou então, o número de valores NA no data.frame é de:
(nrow(avesc) * ncol(avesc)) - length(avesc[!is.na(avesc)])
## [1] 4

O procedimento adotado acima pode ser difícil de entender. Fazer essa pergunta por colunas torna o entendimento mais fácil:

is.na(avesc$urubu) # quais são NA, vetor lógico
##  [1] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# mesmo que
is.na(avesc$urubu) == T
##  [1] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# e o contrário é (quem não é NA)
is.na(avesc$urubu) == F
##  [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [13]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [25]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [37]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [49]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
# ou simplesmente
!is.na(avesc$urubu)
##  [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [13]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [25]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [37]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
## [49]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE

Vetores lógicos TRUE e FALSE podem ser somados. TRUE corresponde a 1, e FALSE a 0. Usando o resultado de is.na(avesc$urubu) (ou qualquer outra variável de avesc) junto à função sum(), teremos então o número de valores faltantes na variável escolhida:

sum(is.na(avesc$urubu)) # quantos sao?
## [1] 1
sum(!is.na(avesc$urubu)) # quantos não são?
## [1] 59
# e, isso é verdadeiro, né?
(sum(is.na(avesc$urubu)) + sum(!is.na(avesc$urubu))) == nrow(avesc)
## [1] TRUE

Podemos perguntar quais posições do vetor lógico oriundo de is.na(avesc$urubu) são correspondentes a NA por meio da função which(). Teremos como resposta um vetor de números inteiros indicando o número das linhas com valores NA na urubu:

which(is.na(avesc$urubu)) # vetor com indices das posições que são NA
## [1] 6

Vamos utilizar agora este resultado para filtrar o data.frame avesc e checar que linha é essa:

avesc[which(is.na(avesc$urubu)), ] # mesma coisa, mas precisa de uma segunda função, então menos parcimonioso
fisionomia urubu carcara seriema
Ce6 Ce NA 20 NA

Podemos filtrar também sem a função which(), usando apenas os vetores lógicos TRUE e FALSE oriundos da função is.na():

avesc[is.na(avesc$urubu), ] # mostra as linhas completas para os registros com NA na coluna urubu
fisionomia urubu carcara seriema
Ce6 Ce NA 20 NA
## para ver se tem NA em uma das tres colunas com nomes de aves: usamos o operador | (quer dizer 'ou')
meufiltro <- is.na(avesc$urubu) | is.na(avesc$carcara) | is.na(avesc$seriema)
sum(is.na(avesc)) # soma dos valores NA nas tres colunas
## [1] 4
avesc[meufiltro, ] # mostra todas as linhas que tem algum valor NA
fisionomia urubu carcara seriema
Ce6 Ce NA 20 NA
CC5 CC 20 10 NA
CL9 CL 19 NA 5
# Esses valores NA, na verdade são AUSENCIA da ave (não avistamento) numa determinada localidade (linha no dado). Portanto, NA neste caso deveria ser de fato 0.

## Então, vamos corrigir estes valores
vl <- is.na(avesc$urubu)
## Podemos ver os valores de vários jeitos
avesc$urubu[vl] # assim
## [1] NA
avesc[vl, "urubu"] # ou assim
## [1] NA
avesc[, "urubu"][vl] # ou assim...
## [1] NA
# se podemos ver, podemos atribuir 0 para esse valor ausentes
avesc$urubu[vl] <- 0

## Continuando, para as outras aves, mostrando variacoes de códigos
avesc$carcara[is.na(avesc$carcara)] <- 0
avesc$seriema[is.na(avesc$seriema) == T] <- 0

## Verificando se substituimos corretamente
avesc[meufiltro, ]
fisionomia urubu carcara seriema
Ce6 Ce 0 20 0
CC5 CC 20 10 0
CL9 CL 19 0 5
# poderiamos ter feito a mudanca de uma vez
aves2[meufiltro, ] # a cópia que fiz no início
fisionomia urubu carcara seriema
Ce6 Ce NA 20 NA
CC5 CC 20 10 NA
CL9 CL 19 NA 5
aves2[meufiltro, ][is.na(aves2[meufiltro, ])] # visualizo só os NAs
## [1] NA NA NA NA
aves2[meufiltro, ][is.na(aves2[meufiltro, ])] <- 0 # atribuo 0

## Agora esses valores são zero, certo?
avesc[avesc$urubu == 0 | avesc$carcara == 0 | avesc$seriema == 0, ]
fisionomia urubu carcara seriema
Ce6 Ce 0 20 0
CC5 CC 20 10 0
CL9 CL 19 0 5

11.2 Colunas com fatores

As colunas com fatores estão codificadas corretamente?

Temos algumas funções úteis para se trabalhar com fatores. A primeira delas se chama table() e é responsável por fazer contagens de valores em fatores ou vetores de texto. Já as funções factor() e as.factor() permitem criar ou definir fatores.

# agora vamos ver a nossa coluna fisionomia, que não importamos como fator
str(avesc)
## 'data.frame':    60 obs. of  4 variables:
##  $ fisionomia: chr  "Ce" "Ce" "Ce" "Ce" ...
##  $ urubu     : num  5 7 5 3 4 0 6 4 2 5 ...
##  $ carcara   : num  18 7 14 12 16 20 19 21 11 9 ...
##  $ seriema   : num  6 6 4 5 4 0 4 10 6 7 ...
avesc$fisionomia
##  [1] "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce" "Ce"
## [16] "Ce" "Ce" "ce" "Ce" "Ce" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC"
## [31] "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CC" "CL" "CL" "CL" "CL" "CL"
## [46] "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL" "CL"
class(avesc$fisionomia)
## [1] "character"

As categorias da variável avesc$fisionomia significam:

  • “CL” = campo limpo;
  • “CC” = campo cerrado;
  • “Ce” = cerrado.

Vamos tabular essa coluna e verificar quantos valores temos para cada categoria:

table(avesc$fisionomia)
CC ce Ce CL
20 1 19 20

Reparem que a categoria ce e Ce são tratadas como diferentes pois o R6 interpreta letras minúsculas e maiúsculas diferentemente. A falta de padronização em dados biológicos tabulados é muito frequente, e trabalhar com scripts permite ao usuário documentar todas as mudanças em etapas que precedem o momento da análise. Por isso, fique sempre atento à padronização e a checagem de dados durante a AED.

Antes de proceder com a correção, vamos fazer uma cópia da variável avesc$fisionomia para fins deste exercício:

fisionomia.copia <- avesc$fisionomia

Digamos que o padrão deve ser Ce, então vamos filtrar os valores presentes em avesc que não correspondem a Ce, isto é, o valor ce:

vl <- avesc$fisionomia == "ce" # quem tem esse valor
avesc$fisionomia[vl] <- "Ce" # corrigindo
table(avesc$fisionomia)
CC Ce CL
20 20 20

Tendo em vista que a diferença é apenas de capitalização entre ce e Ce, poderíamos ter feito simplesmente o exposto abaixo para efeito de correção:

avesc$fisionomia <- fisionomia.copia # volto ao valor original

Primeiro, usamos a cópia dos valores originais e o atribuímos aos valores modificados. Em seguida, mudamos a capitalização das palavras para caixa alta com a função toupper(). Em seguida, tabulamos as categorias:

# corrijo, simplesmente mudando tudo para maiúsculo:
avesc$fisionomia <- toupper(avesc$fisionomia)
table(avesc$fisionomia)
CC CE CL
20 20 20

Porém, se nós tivéssemos importado os dados transformando vetores de texto como fatores, por meio dos argumentos as.is = FALSE OU stringsAsFactors = FALSE, poderíamos proceder da seguinte maneira:

# digamos no entanto, que eu tivesse importado a coluna como fator
avesc$fisionomia <- as.factor(fisionomia.copia)
class(avesc$fisionomia)
## [1] "factor"
levels(avesc$fisionomia) # os níveis ou categorias do fator
## [1] "CC" "ce" "Ce" "CL"
# isso é verdadeiro, certo?:
sort(unique(avesc$fisionomia)) == levels(as.factor(avesc$fisionomia))
## [1] TRUE TRUE TRUE TRUE
# sendo um fator, para corrigir, eu precisaria apenas:
levels(avesc$fisionomia)[2] <- "Ce"
levels(avesc$fisionomia) # pronto, corrigido
## [1] "CC" "Ce" "CL"
table(avesc$fisionomia)
CC Ce CL
20 20 20
## Verificando novamente
str(avesc)
## 'data.frame':    60 obs. of  4 variables:
##  $ fisionomia: Factor w/ 3 levels "CC","Ce","CL": 2 2 2 2 2 2 2 2 2 2 ...
##  $ urubu     : num  5 7 5 3 4 0 6 4 2 5 ...
##  $ carcara   : num  18 7 14 12 16 20 19 21 11 9 ...
##  $ seriema   : num  6 6 4 5 4 0 4 10 6 7 ...
summary(avesc)
fisionomia urubu carcara seriema
CC:20 Min. : 0.00 Min. : 0.00 Min. : 0.000
Ce:20 1st Qu.: 6.75 1st Qu.: 5.00 1st Qu.: 4.000
CL:20 Median :12.00 Median : 9.00 Median : 5.000
NA Mean :11.73 Mean :10.08 Mean : 5.167
NA 3rd Qu.:16.25 3rd Qu.:14.00 3rd Qu.: 6.000
NA Max. :22.00 Max. :24.00 Max. :12.000