Show Introdução aos gráficos de barras em REste artigo concentra-se na criação de gráficos de barras no R. O gráfico de barras ajuda a comparar visualmente os dados e uma das partes mais essenciais dos gráficos. Eles são fáceis de criar e úteis para categorizar dados, para que o usuário possa captar as informações usando uma barra (cada entidade é considerada como barras). A maioria das informações estatísticas escritas no texto é difícil de entender; é por isso que uma ferramenta eficaz conhecida como gráficos de colunas foi amplamente utilizada. Os gráficos de barras são usados quando ocorre uma comparação entre os dados ao longo do tempo. A altura da barra é decidida pelos valores fornecidos como entrada. Nos gráficos de barras, os dados são representados por barras retangulares e até fazem comparações múltiplas. Em alguns lugares, para tabular um gráfico de barra de dados, use a função table () em nossos exemplos. Sintaxe A sintaxe básica para criar um gráfico de barras em R é mostrada abaixo. gráfico de barras (H, xlab, ylab, main, names.arg, col) Descrição dos parâmetros são: H denota altura (vetor ou matriz). Se H é um vetor, os valores determinam as alturas das barras. Se for uma matriz com a opção false, corresponderá às sub-barras e true denota para criar uma barra horizontal.
Como criar um simples gráfico de barras no R?Aqui discutiremos como criar gráficos de barras usando a função barplot () em R, que é muito fácil de implementar com barras verticais e horizontais. No exemplo abaixo, veremos a criação de gráficos usando vetores. temp <- c(20, 25, 27, 23, 22, 26, 29) Resultado: A barra Plot deve ficar assim: O próximo exemplo vem com a inicialização de alguns vetores de números e a criação de um comando table () para contá-los. A largura da barra pode ser ajustada usando um parâmetro width () e espaço por espaço () no gráfico de barras. // Vector numbers are created using function c () x<- c (1, 2, 2, 2, 3, 5, 5, 5, 5, 4) cnt <- table(x) cnt x barplot (cnt, space =1.0) Criando um gráfico de barras usando o conjunto de dados interno de R com barra Horizontal. Para fazer isso, faça horiz = TRUE ou então barras verticais serão desenhadas quando horiz = FALSE (opção padrão). Vamos considerar um conjunto de dados R como: Rural Masculino Rural Feminino Urbano Masculino Urbano Feminino ## 50-54 11, 7 8, 7 15, 4 8, 4 ## 55-59 18, 1 11, 7 24, 3 13, 6 ## 60-64 26, 9 20, 3 37, 0 19, 3 ## 65-69 41, 0 30, 9 54, 6 35, 1 ## 70-74 66, 0 54, 3 71, 1 50, 0 A seguir, um exemplo para plotar o conjunto de dados interno de R. a<- VADeaths (2:5, "Urban Male") barplot(a) # Horizontal bar plot barplot (a, horiz = TRUE) Resultado: Criando um gráfico de barras com etiquetas, títuloO gráfico de barras pode parecer mais elegante adicionando mais parâmetros ao gráfico de barras. Os títulos aqui são atribuídos usando argumentos principais como "Km por distância" e o eixo x como "km e eixo y como" contagem "(rótulos) e o parâmetro col é para adicionar cores à barra (no formato hexadecimal ou RGB) também deve-se tomar cuidado, o número de barras deve ser igual ao número de cores atribuído no vetor de caracteres, se as cores não forem repetidas, a densidade é para linhas de sombreamento nas barras. Títulos e etiquetas podem ser modificados e adicionados aos gráficos de barras. O exemplo a seguir plota o quilômetro por contagem usando parâmetros diferentes. km <- c(11, 14, 14, 16, 17, 19, 17, 16, 17, 18) table (km) km barplot(table(km), main="km per distance", xlab="km", ylab="Count", border="brown", col="yellow", density=5) x <- VADeaths (2:4, "Rural Male") barplot (x, col = "orange", border = "blue") O gráfico de barras para o código acima é fornecido aqui: E cada uma das barras pode receber cores diferentes. Aqui, vamos consertar alguns rótulos. H <- c (6, 11, 27, 2, 44) D <- c("Jan", "feb", "Mar", "Apr", "May") barplot(H, names.arg=D, xlab="Month", ylab="sale", col="Red", main="Salechart", border="yellow") Quando executado, obtemos a seguinte saída: B <- c (1, 3, 21, 35, 22, 37, 17) barplot (B, col="green") barplot (B, main="BARPLOT", xlab="LETTERS", ylab="VALUES", names.arg=c("A", "B", "C", "D", "E", "F", "G"), border="yellow", density=c (90, 70, 50, 40, 30, 20, 10)) mt <- c (3, 1, 10, 12, 14, 7, 9, 11, 18) val <- matrix (mt, nrow = 3, ncol = 3) val barplot (val, col = c ("pink", "yellow", "violet")) No exemplo abaixo, criamos uma matriz para três vetores representando cinco pontos e uma comparação entre eles é feita usando um gráfico de barras. Aqui, estamos usando a função legenda para exibir as legendas. O argumento Bty é destinado a bordas de legenda. Os dados são plotados da seguinte maneira. A <- c (2, 3, 6, 4, 9) B <- c (3, 5, 3, 4, 11) C <- c (5, 5, 7, 7, 15) data<- data.frame(A, B, C) names(data)<- c("Tom", "Harry", "Gilf") barplot(height=as.matrix(data), main="Analysis-1", ylab="Vaccine", beside=TRUE, col=rainbow (5)) legend ("topleft", c("Week1", "Week2", "Week3", "Week4", "Week5"), cex=2.0, bty="n", fill=rainbow (5)) Os gráficos de barras são criados para todas as colunas. (as colunas são agrupadas). O gráfico de grupo utiliza a matriz como valores de entrada. barplot (VADeaths, col = c("blue", "green", "lightcyan", "lavender", "magenta"), // Agora fazendo ao lado = FALSE barplot (VADeaths, col = c("blue", "green", "light cyan", "lavender", "magenta"), Em vez de atribuir as barras continuamente, é eficaz empilhá-las em ordem. Exemplo: counts <- table (VADeaths) barplot(counts, main="Distribution", xlab="Rural Female", col=c("darkblue", "yellow"), legend = rownames(counts)) ConclusãoPortanto, discutimos o básico sobre a criação de gráficos de barras em R. Isso ajudará você a entender conceitos em tempo real para comparação quantitativa. Os gráficos de barras desempenham um papel essencial na visualização de dados. Vimos alguns cenários em tempo real nos gráficos de barras para obter valores categóricos e monitorar a variação de um processo para o conjunto de dados fornecido. Novas variações de gráficos de barras incluem plotagem usando pontos. Os gráficos de barras ajudam a agrupar valores em vários níveis. Artigos recomendadosEste foi um guia para gráficos de barras em R. Aqui discutimos a sintaxe básica para criar um gráfico de barras, atribuir títulos e rótulos usando vários argumentos. você também pode consultar os seguintes artigos para saber mais -
O landscape de recursos para visualização de dados no R pode ser representado por uma divisão em 3 territórios.
Para mais detalhes sobre os recursos gráficos, siga esse link: https://www.stat.ubc.ca/~jenny/STAT545A/block90_baseLatticeGgplot2.html. Para uma descrição completada comparação entre lattice e ggplot2, siga esse link: https://learnr.wordpress.com/2009/08/26/ggplot2-version-of-figures-in-lattice-multivariate-data-visualization-with-r-final-part/ Confira no R Graph Gallery a variedade de gráficos confeccionados com o R. Além dos recursos disponíveis nos territórios supradescritos, pode-se considerar ainda a existência de mais dois conjuntos de recursos: para mapas e gráficos interativos. A visualização de dados geográficos conta com um vários pacotes específicos. Siga os links abaixo para ter uma ideia das funcionalidades: Os recursos para visualização interativa de dados estão distribuídos em vários pacotes. Talvez o mais interessante deles seja o plotly que permite a criação de gráficos interativos a partir da ggplot2 além de possuir funções próprias. Veja em plotly-R a galeria de gráficos. A visualização interativa é voltada para exibicação na WEB. Alguns dos pacotes para isso são estes:
Para explorar os recursos básicos de visualização, serão usados dados reais sobre a venda do modelo Renault Duster extraídos da WEB. Os dados estão disponíveis online em http://www.leg.ufpr.br/~walmes/data/duster_venda_260314.txt. Os dados contém informações sobre o preço de venda (R$, valor) e distância percorrida (km, km) além de outras características descritoras do veículo, como ano de fabricação, cor, tipo de câmbio. #----------------------------------------------------------------------- # Dados de carros Duster à venda no webmotors em 26/03/2014. # Importa a tabela de dados da web. url <- "http://www.leg.ufpr.br/~walmes/data/duster_venda_260314.txt" dus <- read.table(file = url, header = TRUE, sep = "\t", encoding = "utf-8") str(dus) # 'data.frame': 699 obs. of 10 variables: # $ modelo: Factor w/ 11 levels "RENAULT DUSTER 1.6 4X2 16V FLEX 4P MANUAL",..: 3 1 2 2 1 1 2 3 6 2 ... # $ cor : Factor w/ 9 levels "Azul","Branco",..: 5 1 5 5 5 8 6 6 6 6 ... # $ km : int 31442 40800 56000 NA 45000 50000 44000 30000 41000 55000 ... # $ ano : Factor w/ 7 levels "2011/2011","2011/2012",..: 2 2 2 2 2 4 3 4 2 2 ... # $ valor : num 41990 42500 42900 42990 43800 ... # $ cambio: Factor w/ 2 levels "AUTOMÁTICO","MANUAL": 2 2 2 2 2 2 2 2 2 2 ... # $ poten : num 1.6 1.6 1.6 1.6 1.6 1.6 1.6 1.6 2 1.6 ... # $ trac : Factor w/ 2 levels "4X2","4X4": 1 1 1 1 1 1 1 1 1 1 ... # $ cat : Factor w/ 5 levels " "," DYNAMIQUE ",..: 3 1 2 2 1 1 2 3 2 2 ... # $ novo : Factor w/ 2 levels "novo","usado": 2 2 2 2 2 2 2 2 2 2 ... # Cria ano do veículo com extração regex. dus$ano <- factor(gsub(x = as.character(dus$ano), pattern = "/\\d{4}$", replacement = "")) # Quantidade de NA em cada coluna. apply(dus, MARGIN = 2, FUN = function(x) sum(is.na(x))) # modelo cor km ano valor cambio poten trac cat novo # 0 0 132 0 0 0 0 0 0 0 A variável km apresentou mais de uma centena de valores ausentes. A tabela tem 3 variáveis numéricas (km, valor, poten), sendo as demais todas categóricas.
A análise exploratória de variáveis categóricas é praticamente baseada na distribuição das frequências. Por ser uma variável não numérica, não é possível calcular medidas descritivas numéricas de posição (como média, mediada) ou de dispersão (variância, amplitude). Dessa forma, esta-se confinado à visualizações que consideram as frequências. #----------------------------------------------------------------------- # Gráfico de barras e setores. # Tabela de frequência. x <- table(dus$cambio) class(x) # [1] "table" # Se vem da xtabs() também tem classe `table`. x <- xtabs(~cambio, data = dus) class(x) # [1] "xtabs" "table" # Gráfico padrão. # barplot(x) # Com anotações nas margens e cores. barplot(x, xlab = "Tipo de câmbio", ylab = "Frequência absoluta", col = c("seagreen", "yellowgreen")) # Horizontal. barplot(x, horiz = TRUE, xlab = "Tipo de câmbio", ylab = "Frequência absoluta", col = c("seagreen", "#FF9911")) box(bty = "L") # Cores com `green` no vetor de cores `colors()`. grep(pattern = "green", x = colors(), value = TRUE) # [1] "darkgreen" "darkolivegreen" "darkolivegreen1" # [4] "darkolivegreen2" "darkolivegreen3" "darkolivegreen4" # [7] "darkseagreen" "darkseagreen1" "darkseagreen2" # [10] "darkseagreen3" "darkseagreen4" "forestgreen" # [13] "green" "green1" "green2" # [16] "green3" "green4" "greenyellow" # [19] "lawngreen" "lightgreen" "lightseagreen" # [22] "limegreen" "mediumseagreen" "mediumspringgreen" # [25] "palegreen" "palegreen1" "palegreen2" # [28] "palegreen3" "palegreen4" "seagreen" # [31] "seagreen1" "seagreen2" "seagreen3" # [34] "seagreen4" "springgreen" "springgreen1" # [37] "springgreen2" "springgreen3" "springgreen4" # [40] "yellowgreen" # Gráfico de setores. Evite usar referências radiais pois comparações de # arcos são prejudicadas por não estarem alinhadas. pie(x, col = c("#5398ed", rgb(12, 58, 114, max = 255)), main = "Tipo de câmbio") # Para as cores do carro. x <- xtabs(~cor, data = dus) pie(x) Tanto os gráficos de barras (vertical ou horizontal) quanto o de setores (pizza), representam a distribuição de frequência. No entanto, exceto por razões bem específicas, o gráfico de setores deve ser evitado. A percepção sobre do comprimento dos setores é comprometida pela ausência de um sistema de referência linear. Ou seja, o gráfico está em um sistema de referência polar que dificulta a percepção de comprimentos em arco. # Vetor que cores para usar com cada cor de veiculo. cols <- c("blue", "white", "gray50", "Yellow", "gray90", "black", "green4", "red", "red4") cbind(levels(dus$cor), cols) # cols # [1,] "Azul" "blue" # [2,] "Branco" "white" # [3,] "Cinza" "gray50" # [4,] "Indefinida" "Yellow" # [5,] "Prata" "gray90" # [6,] "Preto" "black" # [7,] "Verde" "green4" # [8,] "Vermelho" "red" # [9,] "Vinho" "red4" # Reordenar os níveis do fator e as cores. ord <- order(x, decreasing = TRUE) cols <- cols[ord] x <- x[ord] n <- names(x) dus$cor <- factor(dus$cor, levels = n) cbind(levels(dus$cor), cols) # cols # [1,] "Prata" "gray90" # [2,] "Branco" "white" # [3,] "Preto" "black" # [4,] "Verde" "green4" # [5,] "Cinza" "gray50" # [6,] "Vermelho" "red" # [7,] "Azul" "blue" # [8,] "Indefinida" "Yellow" # [9,] "Vinho" "red4" a <- barplot(x, xaxt = "n", las = 1, col = cols) mtext(side = 2, text = "Frequência absoluta", line = 3) axis(side = 1, at = a, labels = n, las = 2) box(bty = "L") par(mar = c(4.1, 7.1, 2.1, 2.1)) barplot(x, horiz = TRUE, las = 1, col = cols) mtext(side = 2, text = "Cor", line = 5) mtext(side = 1, text = "Frequência absoluta", line = 2) box(bty = "L") # Fecha a janela gráfica para restaturar as configurações. dev.off() # null device # 1 Quando o número de categorias cresce, a leitura do gráfico de barras é naturalmente mais demorada. Porém, se não existe uma ordenação natural nos níveis da variável categória (variável categórica nominal e não ordinal), a ordenação das barras com relação ao valor aprimora a visualização. O uso das barras horizontais é recomendado quando os texto sob o eixo é comprido. O texto na vertical não favorece a rápida leitura, por isso colocá-lo na horizontal é uma boa opção.
#----------------------------------------------------------------------- # Gráficos de barras emplilhadas (stacked) e lado a lado. x <- xtabs(~cambio + ano, data = dus) x # ano # cambio 2011 2012 2013 2014 # AUTOMÁTICO 51 40 100 4 # MANUAL 88 204 180 32 cols <- c("#660d32", "#bc1a5e") # Barras empilhadas. barplot(x, beside = FALSE, xlab = "Ano", ylab = "Frequência absoluta", col = cols) legend("topleft", legend = levels(dus$cambio), fill = cols, bty = "n") box(bty = "L") # Barras lado a lado. barplot(x, beside = TRUE, xlab = "Ano", ylab = "Frequência absoluta", col = cols) legend("topleft", legend = levels(dus$cambio), fill = cols, bty = "n") box(bty = "L") Quando duas ou variáveis categóricas são consideradas, pode-se representar a distribuição de frequência com barras empilhadas ou barras lado a lado. O enfoque desses gráficos é diferente. Barras empilhadas
Barras lado a lado
x # ano # cambio 2011 2012 2013 2014 # AUTOMÁTICO 51 40 100 4 # MANUAL 88 204 180 32 u <- x %*% diag(1/colSums(x)) colnames(u) <- colnames(x) u # # cambio 2011 2012 2013 2014 # AUTOMÁTICO 0.3669065 0.1639344 0.3571429 0.1111111 # MANUAL 0.6330935 0.8360656 0.6428571 0.8888889 # Barras empilhadas relativas. barplot(u, beside = FALSE, xlab = "Ano", ylab = "Frequência relativa", col = cols) legend("topleft", inset = c(0.025, -0.12), xpd = TRUE, ncol = 2, legend = levels(dus$cambio), fill = cols, bty = "n") box(bty = "L") mosaicplot(t(x), off = c(2, 1), col = cols, ylab = "Tipo de câmbio", xlab = "Ano", main = NULL) legend("topleft", inset = c(0.025, -0.12), xpd = TRUE, ncol = 2, legend = levels(dus$cambio), fill = cols, bty = "n") Barras empilhadas padronizadas As barras empilhadas podem ter comprimento padronizado para representar a frequência relativa. Dessa forma é mais facil comprar as frquências relativas. Nesse gráfico as ênfases são:
Gráfico de barras como mosaico Mais um tipo de gráfico interessante é o mosaico. Ele é uma exibição das frequências relativas marginais e condicionais. Tem por objetivo:
#----------------------------------------------------------------------- # Anotações nas barras. x <- xtabs(~cambio + poten, data = dus) x # poten # cambio 1.6 2 # AUTOMÁTICO 0 195 # MANUAL 379 125 # Cores de preenchimento para as barras. cols <- c("#04510a", "#229b2b") # Barras lado a lado. bp <- barplot(t(x), beside = TRUE, col = cols, xlab = "Tipo de câmbio", ylab = "Frequência absoluta") bp # [,1] [,2] # [1,] 1.5 4.5 # [2,] 2.5 5.5 # Calcula a altura de uma palavra em termos da escala y do gráfico. sh <- strheight("um texto qualquer") sh # [1] 9.273014 # Opera com os limites do gráfico armazenados em `par()$usr`. lim <- par()$usr[4] + 3 * sh # Refaz o gráfico com espaço para o texto. barplot(t(x), beside = TRUE, col = cols, ylim = c(0, lim), xlab = "Tipo de câmbio", ylab = "Frequência absoluta") legend("topleft", title = "Potência", legend = c("1.6","2.0"), fill = cols, bty = "n") text(x = c(bp), y = t(x), labels = t(x), pos = 3) box() Se mais variáveis forem envolvidas, o gráfico de mosaico fará a representação com mais divisões nos retângulos. # Mais dimensões. mosaicplot(HairEyeColor, off = 2, col = c("pink", "cyan")) # Obtendo totais para fazer gráficos de barras. dimnames(HairEyeColor) # $Hair # [1] "Black" "Brown" "Red" "Blond" # # $Eye # [1] "Brown" "Blue" "Hazel" "Green" # # $Sex # [1] "Male" "Female" a <- apply(HairEyeColor, MARGIN = c(1, 2), FUN = sum) # Vetor que associa cores conforme os níveis dos fatores às cores usadas # para preenchimento. cols <- c(Brown = "#6b2205", Blue = "#4fb2ff", Green = "#1a9b1e", Blond = "#d8d652", Red = "#bc1405", Black = "#210a08", Hazel = "#a86526") # Mosaico. mosaicplot(a, col = cols[colnames(a)]) mosaicplot(t(a), col = cols[rownames(a)]) # Barras empilhadas. barplot(a, xlab = "Eye", col = cols[rownames(a)]) legend("topright", title = "Hair", legend = rownames(a), fill = cols[rownames(a)], bty = "n") # Barras lado a lado. barplot(a, xlab = "Eye", beside = TRUE, col = cols[rownames(a)]) legend("topright", title = "Hair", legend = rownames(a), fill = cols[rownames(a)], bty = "n") # Visite estes sites para pegar cores. # browseURL("http://www.w3schools.com/html/html_colors.asp") # browseURL("http://html-color-codes.info/")
Para representar a distribuição de frequência de variáveis contínuas tem-se mais opções. A mais simples delas, o histograma, consiste em discretizar os dados agrupando as observações em classes. A frequência das classes é exibida contra as classes. #----------------------------------------------------------------------- # Histograma. # Gráfico básico. # hist(dus$valor) hist(dus$valor, xlab = "Preço de venda (R$)", ylab = "Frequência absoluta", col = "orange") rug(dus$valor) # Se breaks é um escalar então entende-se que é uma *sugestão* para o # número de clases. hist(dus$valor, breaks = 15, xlab = "Preço de venda (R$)", ylab = "Frequência absoluta", col = "orange") rug(dus$valor) # Se breaks é um vetor então entende-se que são os limites para # classificação dos valores. hist(dus$valor, breaks = seq(35000, 75000, by = 2500), xlab = "Preço de venda (R$)", ylab = "Frequência absoluta", col = "#7700B7", sub = "Amplitude de classe de R$ 2500", main = NULL) # Gráfico onde a altura é a densidade e não a frequência. hist(dus$valor, prob = TRUE, breaks = seq(35000, 75000, by = 2500), xlab = "Preço de venda (R$)", ylab = "Densidade", col = "#ba6dff", sub = "Amplitude de classe de R$ 2500", main = NULL) O histograma pode representar duas medidas diferentes, porem relacionadas, de frequência. Como argumento prob = FALSE, a altura da barra é o número de registros em cada classe. Com prob = TRUE, o produto da altura (densidade) pela largura (amplitude de classe) de cada barra corresponde a frequência relativa. A soma das frequências relativas é 1 e, portanto, a área do gráfico coberta pelas barras do histograma é unitária. #----------------------------------------------------------------------- # Anotações sobre um histograma. # Com domínio do R se pode fazer gráficos espetaculares, como por # exemplo esses com variação da tonalidade ou destaque da classe modal. ht <- hist(dus$valor, prob = TRUE, breaks = seq(35000, 75000, 2000), xlab = "Preço de venda (R$)", ylab = "Frequência absoluta", sub = "Amplitude de classe de R$ 2500") rug(dus$valor) # Faz risquinhos no eixo x. # Destacar a barra da classe modal usando outra cor. wm <- which.max(ht$counts) cols <- rep("yellow", length(ht$counts)) cols[wm] <- "red" cols # [1] "yellow" "yellow" "yellow" "yellow" "yellow" "yellow" "yellow" # [8] "red" "yellow" "yellow" "yellow" "yellow" "yellow" "yellow" # [15] "yellow" "yellow" "yellow" "yellow" "yellow" "yellow" plot(ht, col = cols) # Traçar os segmentos que indicam o valor interpolado para a moda. ycoor <- with(ht, counts[wm + 0:1]) xcoor <- with(ht, breaks[wm + 0:1]) segments(xcoor[1], ycoor[1], xcoor[2], ycoor[2], lty = 2) ycoor <- with(ht, counts[wm - 1:0]) xcoor <- with(ht, breaks[wm + 0:1]) segments(xcoor[1], ycoor[1], xcoor[2], ycoor[2], lty = 2) # Por semelhança de triangulos a moda obtida é: ac <- with(ht, diff(breaks[1:2])) d <- with(ht, abs(diff(counts[wm + (-1:1)]))) xmoda <- with(ht, breaks[wm] + (ac * d[1])/sum(d)) xmoda # [1] 49789.47 abline(v = xmoda, lwd = 2) É possível fazer gráficos personalizados com o domínios dos recursos básicos de plotagem do R. O código acima usa a função de alto nível hist() para produzir o histograma. Quando atribuida a um objeto, todos os elementos do histograma ficam salvos para permitir pós processamento (limites e cento das classes, frequência absoluta e relativa, etc). Funções de baixo nível (abline(), segments()) são chamadas para adicionar elementos aos gráficos. Os dois gráficos abaixo fazem uso das funções de baixo para ilustrar o potencial do R para confecção de gráficos. No entanto, tais gráficos podem não ter muita utilidade prática. #-------------------------------------------- # Destaque para a classe modal. plot(ht, col = NULL, lty = 0, ann = FALSE, axes = FALSE) abline(h = seq(0, 100, by = 10), lty = 2) plot(ht, col = cols, ann = FALSE, axes = FALSE, add = TRUE) rug(dus$valor) axis(side = 1, at = seq(35000, 75000, 5000)) axis(side = 2, at = seq(0, 100, by = 10)) box(bty = "L") title(main = "Histograma do valor (R$)", sub = "Dados retirados do webmotors.com", xlab = "Valor (R$)", ylab = "Frequência absoluta") mtext(side = 3, line = 0, text = paste("Amostra de tamanho", length(dus$valor))) mtext(side = 4, line = -1, col = "gray70", outer = TRUE, adj = 0, text = "Feito por Walmes Zeviani - ") legend("topright", fill = "red", legend = "Classe modal", bty = "n") #-------------------------------------------- # Outra variação de um histograma. ht <- hist(dus$valor, seq(35000, 75000, 2000), plot = FALSE) nc <- length(ht$mids) # Número de classes. ac <- diff(ht$breaks[1:2]) # Amplitude de classe. ma <- mean(dus$valor) # Média da amostra. md <- median(dus$valor) # Mediana da amostra. qts <- fivenum(dus$valor)[c(2,4)] # 1Q e 3Q da amostra. modal <- which.max(ht$counts) # Classe modal. modal <- list(x = ht$mids[modal], y = ht$counts[modal]) colseq <- rgb(red = 0.25, blue = 0.7, green = seq(0.1, 0.9, length.out = nc)) plot(ht, col = colseq, ylim = c(0, modal$y + strheight("1")), xlab = "Preço de venda (R$)", ylab = "Frequência absoluta", sub = paste("Amplitude de classe de R$", ac), main = NULL, border = "gray50") rug(dus$valor) text(x = modal$x, y = modal$y, labels = modal$y, pos = 3) arrows(ma, 0, ma, modal$y/3, code = 1, length = 0.15) text(ma, modal$y/3, labels = paste("Média:", round(ma,2)), pos = 3) arrows(md, 0, md, modal$y/6, code = 1, length = 0.15) text(ma, modal$y/6, labels = paste("Mediana:", round(md,1)), pos = ifelse(md<ma, 2, 4)) box() Responda: o que de informação adicional foi acrescentado com as barras mudando de cor? Nada! A variação das cores está se sobrepondo a informação de posição no eixo horizontal. Ou seja, são dois elementos estéticos (posição e preenchimento) mapeando a mesma informação. Uma boa prática na confecção de gráficos e evitar redundância. Pode até ser que o leitor seja atraído pelo visual pouco ortodoxo do gráfico mas há um desperdício de carga cognitiva para processamento dessa informação visual acessória ou meramente estética. #----------------------------------------------------------------------- # Gráficos de densidade. den <- density(dus$valor) plot(den) den # # Call: # density.default(x = dus$valor) # # Data: dus$valor (699 obs.); Bandwidth 'bw' = 1482 # # x y # Min. :33555 Min. :4.340e-09 # 1st Qu.:44402 1st Qu.:1.390e-06 # Median :55250 Median :1.492e-05 # Mean :55250 Mean :2.302e-05 # 3rd Qu.:66098 3rd Qu.:4.304e-05 # Max. :76945 Max. :7.011e-05 # Tipos de função kernel. formals("density.default")$kernel # c("gaussian", "epanechnikov", "rectangular", "triangular", "biweight", # "cosine", "optcosine") den <- density(dus$valor, kernel = "triangular") plot(den) rug(dus$valor) # Controle da largura de banda. den <- density(dus$valor, kernel = "rectangular", bw = 3000) plot(den) rug(dus$valor) abline(v = seq(35000, 75000, 5000), col = "gray50") abline(v = seq(35000, 75000, 1000), col = "gray90") # Realce da classe modal. den <- density(dus$valor/1000) str(den) # List of 7 # $ x : num [1:512] 33.6 33.6 33.7 33.8 33.9 ... # $ y : num [1:512] 5.62e-06 6.73e-06 8.03e-06 9.52e-06 1.13e-05 ... # $ bw : num 1.48 # $ n : int 699 # $ call : language density.default(x = dus$valor/1000) # $ data.name: chr "dus$valor/1000" # $ has.na : logi FALSE # - attr(*, "class")= chr "density" x <- eval(parse(text = den$data.name)) ma <- mean(x) # Média da amostra. md <- median(x) # Mediana da amostra. modal <- which.max(den$y) modal <- list(x = den$x[modal], y = den$y[modal]) plot(den, type = "n", xlab = "Preço de venda (R$ x 1000)", ylab = "Densidade", ylim = c(0, modal$y + strheight("1")), main = "", sub = paste("Bandwidth:", round(den$bw,3))) with(den, polygon(x, y, col = "gray90")) with(modal, { segments(x, 0, x, y, col = 2) text(x, y, labels = sprintf("Moda: %0.2f", x), pos = 3) }) arrows(ma, 0, ma, modal$y/3, code = 1, length = 0.15) text(ma, modal$y/3, labels = sprintf("Média: %0.2f", ma), pos = 3) arrows(md, 0, md, modal$y/6, code = 1, length = 0.15) text(ma, modal$y/6, labels = sprintf("Mediana: %0.2f", md), pos = ifelse(md<ma, 2, 4)) rug(dus$valor) # Warning in rug(dus$valor): some values will be clipped O gráfico de densidade empírica kernel é o sucessor ou evolução do histograma. Esse gráfico calcula a densidade em um ponto \(x\) no domínio da variável por meio de uma função kernel que é, de forma simples, uma função de ponderação, e o resultado e uma soma de frequências ponderada pela distância. Existem 7 funções kernel disponíveis. Visite essa aplicação Shiny para compreender visualmente como funciona a densidade kernel: http://shiny.leg.ufpr.br/walmes/density/. #----------------------------------------------------------------------- # Gráfico de frequência acumulada empírica. y <- ecdf(dus$valor) plot(y) plot(y, xlab = "Preço de venda (R$)", ylab = "Frequência relativa acumulada", cex = NA, verticals = TRUE, main = NULL) # Destacando a frequência de veículos com preço de 50 à 60 mil. lim <- c(50000, 60000) ptbl <- prop.table(table(cut(dus$valor, breaks = c(-Inf, lim, Inf)))) cs <- cumsum(ptbl)[seq_along(lim)] # As observações do intervalo correspondem ao valor 1. ins <- findInterval(dus$valor, vec = lim) table(ins) # ins # 0 1 2 # 254 333 112 plot(y, xlab = "Preço de venda (R$)", ylab = "Frequência relativa acumulada", cex = NA, col = "#00af20", lwd = 2, verticals = TRUE, main = NULL) segments(x0 = lim, y0 = 0, x1 = lim, y1 = cs, lty = 2) segments(x0 = lim, y0 = cs, x1 = par() $usr[3], y1 = cs, lty = 2) arrows(x0 = lim[1], y0 = cs[1], x1 = lim[1], y1 = cs[2], code = 3, length = 0.15) text(x = lim[1], y = median(cs), labels = sprintf("%0.3f", ptbl[2]), srt = 90, adj = c(0.5,-0.5)) rug(dus$valor[ins == 1L], col = "#00af20") rug(dus$valor[ins != 1L], col = "black")
#----------------------------------------------------------------------- # Diagrama de dispersão. dus2 <- subset(dus, complete.cases(cbind(km, valor)), select = c(cambio, valor, km)) dus2 <- transform(dus2, km = km/1000, valor = valor/1000) # Diagrama de dispersão básico. plot(valor ~ km, data = dus2) # Adicionar uma linha de tendência suave. plot(valor ~ km, data = dus2, xlab = "Distância percorrida (km)", ylab = "Preço de venda (R$)") with(dus2, { lines(lowess(x = km, y = valor), lwd = 2, col = "#ff0050") }) # Usar cores diferentes para identificar o tipo de câmbio, com linhas # de tendência e grid. cols <- c("#db0d9d", "#0c0099") levels(dus2$cambio) # [1] "AUTOMÁTICO" "MANUAL" plot(valor ~ km, data = dus2, type = "n", xlab = "Distância percorrida (km)", ylab = "Preço de venda (R$)") i <- 0 by(dus2, INDICES = dus2$cambio, FUN = function(data) { i <<- i + 1 with(data, { points(x = km, y = valor, col = cols[i], pch = 19) lines(lowess(x = km, y = valor), col = cols[i], lwd = 1.5) rug(km, side = 1, col = cols[i]) rug(valor, side = 4, col = cols[i]) invisible() }) }) # dus2$cambio: AUTOMÁTICO # NULL # -------------------------------------------------------- # dus2$cambio: MANUAL # NULL legend("top", lty = 1, col = cols, legend = levels(dus2$cambio), lwd = 1.5, bty = "n") grid() O diagrama de dispersão é um dos gráficos mais fáceis de produzir pois não requer pré-processamento dos dados. Ou seja, o gráfico exibe todos os pares de pontos, diferente dos gráficos de barras que presentam o resultado de uma agregação dos dados: as frequências absolutas ou relativas. Por outro lado, quando-se deseja destacar categorias usando cores ou símbolos, é necessário trabalho manual. Uma das principais vantagens da lattice e ggplot2 é fazer isso de forma bem mais simples.
#----------------------------------------------------------------------- # Preço em função dos anos. boxplot(valor ~ ano, data = dus) # Edita níveis do fator. levels(dus$cat) # [1] " " " DYNAMIQUE " " EXPRESSION " " TECH ROAD " # [5] " TECH ROAD II " levels(dus$cat) <- trimws(levels(dus$cat)) dus2 <- droplevels(subset(dus, cat != "")) dus2 <- transform(dus2, valor = valor/1000, km = km/1000) boxplot(valor ~ cat, data = dus2, xlab = "Modelo", ylab = "Preço de venda (R$)") # Larguras proporcionais à raiz da quantidade em cada grupo. boxplot(valor ~ cat, data = dus2, varwidth = TRUE, pars = list(boxwex = 1), xlab = "Modelo", ylab = "Preço de venda (R$)") table(dus2$cat) # # DYNAMIQUE EXPRESSION TECH ROAD TECH ROAD II # 442 51 164 2 # Indicação do valor da média. mds <- with(dus2, tapply(valor, cat, mean)) mds # DYNAMIQUE EXPRESSION TECH ROAD TECH ROAD II # 52.75835 47.34853 59.79432 69.24500 bp <- boxplot(valor ~ cat, data = dus2) bp # $stats # [,1] [,2] [,3] [,4] # [1,] 42.90 38.000 49.0000 65.990 # [2,] 48.99 44.195 56.9995 65.990 # [3,] 51.90 46.999 59.9000 69.245 # [4,] 55.50 49.900 62.9000 72.500 # [5,] 65.00 56.990 68.4000 72.500 # # $n # [1] 442 51 164 2 # # $conf # [,1] [,2] [,3] [,4] # [1,] 51.41075 45.7368 59.17201 61.97184 # [2,] 52.38925 48.2612 60.62799 76.51816 # # $out # [1] 65.90000 66.82871 68.50000 66.99000 65.90000 66.90000 66.90000 67.70000 # [9] 60.00000 # # $group # [1] 1 1 1 1 1 1 1 1 2 # # $names # [1] "DYNAMIQUE" "EXPRESSION" "TECH ROAD" "TECH ROAD II" # Amplitude interquartílica. aiq <- bp$stats[4, ] - bp$stats[2, ] l <- bp$stats[2, ] - 1.5 * aiq u <- bp$stats[4, ] + 1.5 * aiq i <- seq_along(u) boxplot(valor ~ cat, data = dus2, notch = TRUE, col = "#ff5c21", xlab = "Modelo", ylab = "Preço de venda (R$)") # Warning in bxp(structure(list(stats = structure(c(42.9, 48.99, 51.9, # 55.5, : some notches went outside hinges ('box'): maybe set notch=FALSE points(x = 1:nlevels(dus2$cat), y = mds, pch = 4, cex = 1.5) segments(x0 = i - 0.5, x1 = i + 0.5, y0 = l, y1 = l, col = "gray50", lty = 3) segments(x0 = i - 0.5, x1 = i + 0.5, y0 = u, y1 = u, col = "gray50", lty = 3) O gráfico/diagrama de caixas e bigodes (box and whiskers) representa os 5 números de Tukey: mínimo, 1 quartil, mediana, 3 quartil e máximo. Alguns pontos são represetados além da extremidade do bigode porque ultrapassam a linha imaginária construída baseana na amplitude interquartílica (AIQ = 3 quartil - 1 quartil). A opção notch = TRUE faz um entalhe para representar o intervalo de confiança para a mediana, baseados na distribuição normal assintótica da mediana. Visite ?boxplot.stats para mais detalhes.
#----------------------------------------------------------------------- # Gráficos com o valor para a média e barra de erro para o # desvio-padrão. res <- aggregate(valor ~ cat, data = dus2, FUN = function(x) { c(m = mean(x), s = sd(x)) }) # Criando os limites superior e inferior. res <- transform(res, lwr = valor[, 1] - valor[, 2], upr = valor[, 1] + valor[, 2], catf = as.integer(cat)) res # cat valor.m valor.s lwr upr catf # 1 DYNAMIQUE 52.758352 4.968483 47.78987 57.72684 1 # 2 EXPRESSION 47.348529 4.625478 42.72305 51.97401 2 # 3 TECH ROAD 59.794317 3.986051 55.80827 63.78037 3 # 4 TECH ROAD II 69.245000 4.603265 64.64173 73.84827 4 # dev.off() # Com boxplot e pontos dispersos dos lados. xlim <- extendrange(x = 1:nlevels(dus2$cat), f = 0.1) ylim <- extendrange(x = c(res$lwr, res$upr, dus2$valor), f = 0.1) par(mar = c(5.1, 4.1, 4.1, 0)) layout(matrix(c(1, 2), ncol = 2), widths = c(0.85, 0.15)) with(dus2, { plot.default(x = jitter(as.integer(cat), factor = 0.25) - 0.2, y = valor, xaxt = "n", ann = FALSE, col = "gray50", xlim = xlim, ylim = ylim)}) grid() with(res, { points(x = catf, y = valor[, "m"], pch = 19) arrows(catf, lwr, catf, upr, code = 3, angle = 90, length = 0.05) axis(side = 1, at = catf, labels = as.character(cat), cex.axis = 0.95) }) title(xlab = "Categoria", ylab = "Valor (R$)") mtext(side = 3, line = 0, text = expression("Barras de erro representam " * bar(x) %+-% 1 * s)) boxplot(valor ~ cat, at = 1:nlevels(dus2$cat) + 0.2, col = "gray45", data = dus2, add = TRUE, ann = FALSE, axes = FALSE, pars = list(boxwex = 0.1)) par(mar = c(5.1, 0.1, 4.1, 1)) yhist <- hist(dus2$valor, plot = FALSE, breaks = 20) with(yhist, { plot(x = NULL, y = NULL, ann = FALSE, axes = FALSE, ylim = ylim, xlim = c(0, max(density)))}) rug(side = 2, dus2$valor) snc <- 1:length(yhist$mids) with(yhist, { rect(0, breaks[snc], density[snc], breaks[snc+1], col = "gray70")}) den <- density(dus2$valor) with(den, { lines(x = y, y = x, col = "red", lwd = 2) }) |