Quais são as boas técnicas de visualização de dados para comparar distribuições?

25

Estou escrevendo minha tese de doutorado e percebi que confio excessivamente em gráficos de caixas para comparar distribuições. Quais outras alternativas você gosta para realizar essa tarefa?

Também gostaria de perguntar se você conhece algum outro recurso, como a galeria R, na qual eu possa me inspirar com diferentes idéias sobre visualização de dados.

pedrosaurio
fonte
6
Eu acho que a escolha também depende dos recursos que você deseja comparar. Você pode considerar histogramas hist; densidades suavizadas density; Plotagens de QQ qqplot; parcelas de caule e folhas (um pouco antigas) stem. Além disso, o teste de Kolmogorov-Smirnov pode ser um bom complemento ks.test.
11
Que tal um histograma, uma estimativa de densidade kernal ou um gráfico de violino?
1328 Alexander
Os gráficos de hastes e folhas são como histogramas, mas com o recurso adicional de permitir determinar o valor exato de cada observação. Ele contém mais informações sobre os dados do que você obtém de um boxplot ou q histograma.
Michael R. Chernick
2
@ Procrastinator, que tem as respostas de uma boa resposta, se você quiser elaborá-lo um pouco, você pode converter isso em resposta. Pedro, você também pode se interessar por isso , que abrange a exploração gráfica inicial de dados. Não é exatamente o que você está pedindo, mas pode ser do seu interesse.
gung - Restabelece Monica
11
Obrigado pessoal, estou ciente dessas opções e já usei algumas delas. Certamente não explorei o enredo das folhas. Eu vou ter um olhar mais profundo sobre o link que você forneceu e em 's @Procastinator resposta
pedrosaurio

Respostas:

24

Vou elaborar meu comentário, conforme sugerido por @gung. Também incluirei o enredo de violino sugerido por @Alexander, para ser completo. Algumas dessas ferramentas podem ser usadas para comparar mais de duas amostras.

# Required packages

library(sn)
library(aplpack)
library(vioplot)
library(moments)
library(beanplot)

# Simulate from a normal and skew-normal distributions
x = rnorm(250,0,1)
y = rsn(250,0,1,5)

# Separated histograms
hist(x)
hist(y)

# Combined histograms
hist(x, xlim=c(-4,4),ylim=c(0,1), col="red",probability=T)
hist(y, add=T, col="blue",probability=T)

# Boxplots
boxplot(x,y)

# Separated smoothed densities
plot(density(x))
plot(density(y))

# Combined smoothed densities
plot(density(x),type="l",col="red",ylim=c(0,1),xlim=c(-4,4))
points(density(y),type="l",col="blue")

# Stem-and-leaf plots
stem(x)
stem(y)

# Back-to-back stem-and-leaf plots
stem.leaf.backback(x,y)

# Violin plot (suggested by Alexander)
vioplot(x,y)

# QQ-plot
qqplot(x,y,xlim=c(-4,4),ylim=c(-4,4))
qqline(x,y,col="red")

# Kolmogorov-Smirnov test
ks.test(x,y)

# six-numbers summary
summary(x)
summary(y)

# moment-based summary
c(mean(x),var(x),skewness(x),kurtosis(x))
c(mean(y),var(y),skewness(y),kurtosis(y))

# Empirical ROC curve
xx = c(-Inf, sort(unique(c(x,y))), Inf)
sens = sapply(xx, function(t){mean(x >= t)})
spec = sapply(xx, function(t){mean(y < t)})

plot(0, 0, xlim = c(0, 1), ylim = c(0, 1), type = 'l')
segments(0, 0, 1, 1, col = 1)
lines(1 - spec, sens, type = 'l', col = 2, lwd = 1)

# Beanplots
beanplot(x,y)

# Empirical CDF
plot(ecdf(x))
lines(ecdf(y))

Eu espero que isso ajude.

user10525
fonte
14

Depois de explorar um pouco mais sobre suas sugestões, encontrei esse tipo de complemento para complementar a resposta do @Procastinator. É chamado de 'enxame de abelhas' e é uma mistura de trama de caixa com trama de violino com o mesmo nível de detalhe que a trama de dispersão.

pacote beeswarm R

exemplo de trama de abelhas

pedrosaurio
fonte
2
Eu também incluí beanplot.
7

Uma nota:

Você deseja responder perguntas sobre seus dados e não criar perguntas sobre o próprio método de visualização. Muitas vezes, chato é melhor. Também facilita a comparação de comparações.

Uma resposta:

A necessidade de formatação simples além do pacote base de R provavelmente explica a popularidade do pacote ggplot de Hadley em R.

library(sn)
library(ggplot2)

# Simulate from a normal and skew-normal distributions
x = rnorm(250,0,1)
y = rsn(250,0,1,5)


##============================================================================
## I put the data into a data frame for ease of use
##============================================================================

dat = data.frame(x,y=y[1:250]) ## y[1:250] is used to remove attributes of y
str(dat)
dat = stack(dat)
str(dat)

##============================================================================
## Density plots with ggplot2
##============================================================================
ggplot(dat, 
     aes(x=values, fill=ind, y=..scaled..)) +
        geom_density() +
        opts(title = "Some Example Densities") +
        opts(plot.title = theme_text(size = 20, colour = "Black"))

ggplot(dat, 
     aes(x=values, fill=ind, y=..scaled..)) +
        geom_density() +
        facet_grid(ind ~ .) +
        opts(title = "Some Example Densities \n Faceted") +
        opts(plot.title = theme_text(size = 20, colour = "Black"))

ggplot(dat, 
     aes(x=values, fill=ind)) +
        geom_density() +
        facet_grid(ind ~ .) +
        opts(title = "Some Densities \n This time without \"scaled\" ") +
        opts(plot.title = theme_text(size = 20, colour = "Black"))

##----------------------------------------------------------------------------
## You can do histograms in ggplot2 as well...
## but I don't think that you can get all the good stats 
## in a table, as with hist
## e.g. stats = hist(x)
##----------------------------------------------------------------------------
ggplot(dat, 
     aes(x=values, fill=ind)) +
        geom_histogram(binwidth=.1) +
        facet_grid(ind ~ .) +
        opts(title = "Some Example Histograms \n Faceted") +
        opts(plot.title = theme_text(size = 20, colour = "Black"))

## Note, I put in code to mimic the default "30 bins" setting
ggplot(dat, 
     aes(x=values, fill=ind)) +
        geom_histogram(binwidth=diff(range(dat$values))/30) +
        opts(title = "Some Example Histograms") +
        opts(plot.title = theme_text(size = 20, colour = "Black"))

Finalmente, descobri que adicionar um plano de fundo simples ajuda. Foi por isso que escrevi "bgfun", que pode ser chamado por panel.first

bgfun = function (color="honeydew2", linecolor="grey45", addgridlines=TRUE) {
    tmp = par("usr")
    rect(tmp[1], tmp[3], tmp[2], tmp[4], col = color)
    if (addgridlines) {
        ylimits = par()$usr[c(3, 4)]
        abline(h = pretty(ylimits, 10), lty = 2, col = linecolor)
    }
}
plot(rnorm(100), panel.first=bgfun())

## Plot with original example data
op = par(mfcol=c(2,1))
hist(x, panel.first=bgfun(), col='antiquewhite1', main='Bases belonging to us')
hist(y, panel.first=bgfun(color='darkolivegreen2'), 
    col='antiquewhite2', main='Bases not belonging to us')
mtext( 'all your base are belong to us', 1, 4)
par(op)
geneorama
fonte
(+1) Boa resposta. Eu adicionariaalpha=0.5 ao primeiro gráfico (a geom_density()) para que as partes sobrepostas não fiquem ocultas.
smillig
Eu concordo com o alpha = 0,5 Eu não conseguia lembrar a sintaxe!
geneorama
7

Aqui está um bom tutorial do blog Flowing Data, de Nathan Yau, usando dados de criminalidade em nível estadual e norte-americano. Isto mostra:

  • Gráficos de caixa e bigode (que você já usa)
  • Histogramas
  • Gráficos de densidade do kernel
  • Parcelas de tapete
  • Parcelas para violino
  • Gráficos de feijão (uma combinação estranha de gráfico de caixa, gráfico de densidade, com um tapete no meio).

Ultimamente, vejo-me plotando CDFs muito mais que histogramas.

Dimitriy V. Masterov
fonte
11
+1 para gráficos de densidade do kernel. Eles são muito menos "ocupados" do que os histogramas para planejar várias populações.
Doresoom
3

Existe um conceito especificamente para comparar distribuições, que deve ser mais conhecido: a distribuição relativa.

Y0 0,Y com funções de distribuição cumulativaF0 0,F e queremos compará-los, usando F0 0 como referência.

Definir

R=F0 0(Y)
A distribuição da variável aleatória R é a distribuição relativa de Ycom Y0 0como referência. Note que nós temos issoF0 0(Y0 0) tem sempre a distribuição uniforme (com variáveis ​​aleatórias contínuas, se as variáveis ​​aleatórias forem discretas, isso será aproximado).

Vamos ver um exemplo. O site http://www.math.hope.edu/swanson/data/cellphone.txt fornece dados sobre a duração da última ligação telefônica de estudantes do sexo masculino e feminino. Vamos expressar a distribuição da duração da ligação telefônica para estudantes do sexo masculino, tendo como referência as estudantes do sexo feminino.

Distribuição relativa da duração da ligação telefônica, homens comparados com mulheres

Podemos ver imediatamente que os homens (nesta turma da faculdade ...) tendem a ter ligações telefônicas mais curtas que as mulheres ... e isso é expresso diretamente, de uma maneira muito direta. Nox são mostradas as proporções na distribuição das mulheres, e podemos ler que, por exemplo, durante o tempo T(seja o que for, seu valor não é mostrado), de modo que 20% das chamadas de mulheres foram menores (ou iguais) a isso, a densidade relativa dos homens nesse intervalo varia entre 1,3 e 1,4. Se aproximarmos (mentalmente do gráfico) a densidade relativa média nesse intervalo como 1,35, veremos que a proporção de homens nesse intervalo é cerca de 35% maior que a proporção de mulheres. Isso corresponde a 27% dos homens nesse intervalo.

Também podemos fazer o mesmo gráfico com intervalos de confiança pontuais em torno da curva de densidade relativa:

gráfico de distribuição relativa com intervalo de confiança pontual

As amplas faixas de confiança nesse caso refletem o pequeno tamanho da amostra.

Há um livro sobre esse método: Handcock

O código R para o gráfico está aqui:

phone <-  read.table(file="phone.txt", header=TRUE)
library(reldist)
men  <-  phone[, 1]
women <-  phone[, 3]
reldist(men, women)
title("length of mens last phonecall with women as reference")

Para o último gráfico, mude para:

reldist(men, women, ci=TRUE)
title("length of mens last phonecall with women as reference\nwith pointwise confidence interval (95%)")

Observe que as parcelas são produzidas com o uso da estimativa da densidade do kernel, com o grau de suavidade escolhido via gcv (validação cruzada generalizada).

Mais alguns detalhes sobre a densidade relativa. DeixeiQ0 0 ser a função quantil correspondente a F0 0. Deixeir ser um quantil de R com yro valor correspondente na escala de medição original. Então a densidade relativa pode ser escrita como

g(r)=f(Q0 0(r))f0 0(Q0 0(r))
ou na escala de medição original como g(r)=f(yr)f0 0(yr). Isso mostra que a densidade relativa pode ser interpretada como uma razão de densidades. Mas, na primeira forma, com argumentor, é também uma densidade por direito próprio, integrando a uma ao longo do intervalo (0 0,1 1). Isso o torna um bom ponto de partida para inferência.
kjetil b halvorsen
fonte
1

Eu gosto de apenas estimar as densidades e plotá-las,

head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

library(ggplot2)
ggplot(data = iris) + geom_density(aes(x = Sepal.Length, color = Species, fill = Species), alpha = .2)

insira a descrição da imagem aqui

TrynnaDoStat
fonte
Por que você pinta o interior do pdf (abaixo da curva)?
wolfies
Eu acho que parece mais bonito.
TrynnaDoStat
Talvez - mas possa transmitir a impressão incorreta - de transmitir massa ou área, isso possa ser visualmente inapropriado.
wolfies
11
Transmite massa de probabilidade empírica.
Lepidopterist