2013-03-03 14 views
5

Vorrei plottare ciascuna colonna di una matrice come un grafico a scatole e quindi etichettare i valori anomali in ciascun grafico a scatole come il nome della riga a cui appartengono nella matrice. Per utilizzare un esempio:Etichettatura di valori anomali su boxplot in R

vv=matrix(c(1,2,3,4,8,15,30),nrow=7,ncol=4,byrow=F) 
rownames(vv)=c("one","two","three","four","five","six","seven") 
boxplot(vv) 

desidero etichettare il valore anomalo in ogni trama (in questo caso 30) come il nome della riga a cui appartiene, quindi in questo caso 30 appartiene alla riga 7. V'è un facile modo di fare questo? Ho visto domande simili a questa domanda, ma nessuna sembrava aver funzionato come voglio io.

+0

Siamo spiacenti, ci siamo. – user1836894

risposta

3

Nell'esempio fornito è un po 'noioso perché sono tutti la stessa riga. ma qui è il codice:

bxpdat <- boxplot(vv) 
text(bxpdat$group,            # the x locations 
    bxpdat$out,            # the y values 
    rownames(vv)[which(vv == bxpdat$out, arr.ind=TRUE)[, 1]], # the labels 
    pos = 4) 

Questo raccoglie le rownames valori uguali alla lista "out" (cioè, i valori erratici) nel risultato di boxplot. Boxplot chiama e restituisce i valori da boxplot.stats. Date un'occhiata a:

str(bxpdat) 
+0

Questo flag non falsificherà erroneamente se ci sono due schemi di box con mezzi diversi se c'è un punto dati che è un outlier in uno e non nell'altro? –

+0

Siete invitati a pubblicare un esempio che rappresenta le vostre preoccupazioni. Vedo solo un boxplot nella domanda postata. –

4

@ soluzione DWin funziona molto bene per un singolo boxplot, ma non riuscirà a tutto con i valori duplicati, come il set di dati che ho creato:

#Create data 
set.seed(1) 
basenums <- c(1,2,3,4,8,15,30) 
vv=matrix(c(basenums, sample(basenums), 1-basenums, 
      c(0, 29, 30, 31, 32, 33, 60)),nrow=7,ncol=4,byrow=F) 
dimnames(vv)=list(c("one","two","three","four","five","six","seven"), 1:4) 

Su questo insieme di dati, @ la soluzione di DWin dà:

enter image description here

che è falso, perché nel quarto esempio, non è possibile per il minimo e il massimo di essere in t lui stessa fila.

Questa soluzione è mostruosa (e spero possa essere semplificata), ma efficace.

#Reshape data 
vv_dat <- as.data.frame(vv) 
vv_dat$row <- row.names(vv_dat) 
library(reshape2) 
new_vv <- melt(vv_dat, id.vars="row") 

#Get boxplot data 
bxpdat <- as.data.frame(boxplot(value~variable, data=new_vv)[c("out", "group")]) 

#Get matches with boxplot data 
text_guide <- do.call(rbind, apply(bxpdat, 1, 
    function(x) new_vv[new_vv$value==x[1]&new_vv$variable==x[2], ])) 

#Add labels 
with(text_guide, text(x=as.numeric(variable)+0.2, y=value, labels=row)) 

enter image description here

0

Oppure si può semplicemente eseguire il codice da this blog post:

source("https://raw.githubusercontent.com/talgalili/R-code-snippets/master/boxplot.with.outlier.label.r") # Load the function 
set.seed(6484) 
y <- rnorm(20) 
x1 <- sample(letters[1:2], 20,T) 
lab_y <- sample(letters, 20) 
# plot a boxplot with interactions: 
boxplot.with.outlier.label(y~x1, lab_y) 

(che gestisce molteplici valori anomali, che sono vicini l'uno all'altro)

enter image description here

+0

che il codice sorgente non è più valido –

+1

Grazie @DavidPell - ho riparato da usare: https://raw.githubusercontent.com/talgalili/R-code-snippets/master/boxplot.with.outlier.label.r –

0

@ sebastian-c Questa è una leggera modifica della soluzione DWin che sembrano lavorare con più generalità

bx1<-boxplot(pb,las=2,cex.axis=.8) 
if(length(bx1$out)!=0){ 
    ## get the row of each outlier 
    out.rows<-sapply(1:length(bx1$out),function(i) which(vv[,bx1$group[i]]==bx1$out[i])) 
    text(bx1$group,bx1$out, 
    rownames(vv)[out.rows], 
    pos=4 
) 
} 
5

Oppure, in alternativa, è possibile utilizzare la funzione "Boxplot" dal pacchetto {auto} quali etichette valori anomali per voi.

consultare il seguente link: http://www.inside-r.org/packages/cran/car/docs/Boxplot

Molto più facile!

+0

Link senza esempi di utilizzo non costituiscono risposte; si prega di fornire il codice di esempio – MichaelChirico

4

C'è un modo semplice. Si noti che b in Boxplot nelle righe seguenti è una lettera maiuscola.

library(car) 

Boxplot(y ~ x, id.method="y")