2012-03-25 7 views
12

Ich habe einen Datenrahmen, der wie folgt aussieht:Gantt Stil Zeitliniendiagramm (in der Basis R)

 person n start end 
1   sam 6  0 6 
2  greg 5  6 11 
3  teacher 4 11 15 
4   sam 4 15 19 
5  greg 5 19 24 
6  sally 5 24 29 
7  greg 4 29 33 
8   sam 3 33 36 
9  sally 5 36 41 
10 researcher 6 41 47 
11  greg 6 47 53 

Wo beginnen und Ende sind Zeiten oder Dauern (sam sprach 0-6; greg 6-11 etc.). n ist wie lang (in diesem Fall # von Wörtern) die Person sprach. Ich möchte dies als eine Zeitlinie in der Basis R plotten (ich kann schließlich eine ähnliche Frage mit ggplot2 stellen, aber diese Antwort ist spezifisch für die Basis R [wenn ich Base sage, meine ich die Pakete, die mit einer Standardinstallation kommen]).

Die y-Achse wird von Person und die x-Achse wird Zeit sein. Hoffentlich wird das Endprodukt sieht ungefähr so ​​für die Daten über:

Timeline_Graph

Ich mag würde Basis R verwenden, um dies zu machen. Ich bin mir nicht sicher, wie ich das angehen soll. Meine Gedanken sind, ein Punktdiagramm zu verwenden und ein Punktdiagramm zu zeichnen, aber die Punkte wegzulassen. Dann gehe mit quadratischen Endsegmenten darüber. Ich bin mir nicht sicher, wie das funktioniert, da die Segmente numerische x- und y-Punkte benötigen, um die Segmente und die y-Achse kategorisch zu machen. Ein weiterer Gedanke besteht darin, die Faktoren in Zahlen umzuwandeln (jedem Faktor eine Zahl zuzuweisen) und als leeres Streudiagramm zu plotten und dann mit quadratischen Endliniensegmenten fortzufahren. Dies könnte ein mächtiges Werkzeug auf meinem Gebiet sein, das Sprachmuster betrachtet.

Ich danke Ihnen im Voraus für Ihre Hilfe.

PS das Argument für quadratische Segmente beendet Linie istsegments(... , lend=2)Zeit zu sparen diese Informationen suchen für die oben nicht vertraut mit allen Segment Argumente.

Antwort

8

Während die y-Achse ist kategorisch alles, was Sie tun müssen, um Zahlen zu den Kategorien zuordnen (1: 5) und sie verfolgen. Wenn Sie den Standardwert as.numeric() des Faktors verwenden, werden diese in der Regel alphabetisch nummeriert, aber Sie sollten dies trotzdem überprüfen. Machen Sie Ihren Plot mit dem Argument xaxt = 'n'. Verwenden Sie dann den Befehl axis(), um eine y-Achse einzufügen.

axis(2, 1:5, myLabels) 

Beachten Sie, dass, wenn Sie den einzigen Weg sind Plotten Dinge zu platzieren mit einer Zahl ist. Kategorische x- oder y-Werte sind immer nur die Zahlen 1: nKategorien mit Kategorienamen-Beschriftungen anstelle der Zahlen auf der Achse.

Etwas wie das Folgende bringt Sie nahe genug (vorausgesetzt, Ihr data.frame-Objekt heißt datf) ...

datf$pNum <- as.numeric(datf$person) 
plot(datf$pNum, xlim = c(0, 53), type = 'n', yaxt = 'n', xlab ='Duration (words)', ylab = 'person', main = 'Speech Duration') 
axis(2, 1:5, sort(unique(datf$person)), las = 2, cex.axis = 0.75) 
with(datf, segments(start, pNum, end, pNum, lwd = 3, lend=2)) 
+0

sehr nett. Das entspricht ziemlich genau dem, wonach ich gefragt habe (innerhalb des Basisparameters) und ich kann es von hier aus nehmen. Sehr gute Arbeit. –

+0

Ich hoffe, es macht Ihnen nichts aus, aber ich habe das Stück Code ', lend = 2' in Ihre' segment' Verwendung gesteckt. –

+0

kein Problem ...:) .- – John

28

Sie sagen, Sie wollen eine Basis-R-Lösung, aber Sie sagen nicht, warum. Da dies eine Zeile Code in ggplot ist, zeige ich dies trotzdem.

library(ggplot2) 
ggplot(dat, aes(colour=person)) + 
    geom_segment(aes(x=start, xend=end, y=person, yend=person), size=3) + 
    xlab("Duration") 

enter image description here

+0

es klingt wie er er alle anderen außerhalb Abhängigkeiten für ein Paket zu entwickeln, und versucht zu halten, es auf diese Weise vermieden hat: http://stackoverflow.com/questions/9857787/collapse-columns-by-grouping- variabel in der Basis – Chase

+0

Er könnte auch mehr Kontrolle über das Aussehen haben wollen, um Basisgrafiken besser zu verstehen, um sie mit anderen Basisgrafiken zu integrieren, oder einfach nur eine Vorliebe haben. Oh, und das ist nicht wirklich eine Zeile. Sie haben dort minimal 2 Zeilen, die leicht als 3 interpretiert werden, und Sie haben install.packages ('ggplot2') vergessen. – John

+1

@Andrie, das ist sehr nett. Der Grund, warum ich ggplot nicht verwenden möchte, ist Chase, ich habe alle Abhängigkeiten außer wordcloud vermieden (da dieses Paket einige Codierungen in C enthält, bin ich nicht dazu in der Lage). Mit dieser Funktion wird die Funktion plotten, aber auch einen verarbeiteten Datenframe zurückgeben, der an ggplot übergeben werden kann (ich möchte dies als Beispiel in meinem Paket zeigen, muss aber '#' verwenden, damit der Code die Paketerstellung passiert) Der Grund, warum ich mich für ggplot interessiere, ist, dass ich die gleiche Idee für wiederholte Messungen verwenden werde und die Facettierung wird hier nett sein. "Tolle Arbeit Andrie. +1 –

15

Ziemlich ähnlich wie @ John Ansatz, aber da ich es tat, werde ich es posten :)

Hier ist eine generische Funktion ein Gantt (keine Abhängigkeiten) zu zeichnen:

plotGantt <- function(data, res.col='resources', 
         start.col='start', end.col='end', res.colors=rainbow(30)) 
{ 
    #slightly enlarge Y axis margin to make space for labels 
    op <- par('mar') 
    par(mar = op + c(0,1.2,0,0)) 

    minval <- min(data[,start.col],na.rm=T) 
    maxval <- max(data[,end.col],na.rm=T) 

    res.colors <- rev(res.colors) 
    resources <- sort(unique(data[,res.col]),decreasing=T) 

    plot(c(minval,maxval), 
     c(0.5,length(resources)+0.5), 
     type='n', xlab='Duration',ylab=NA,yaxt='n') 
    axis(side=2,at=1:length(resources),labels=resources,las=1) 
    for(i in 1:length(resources)) 
    { 
    yTop <- i+0.1 
    yBottom <- i-0.1 
    subset <- data[data[,res.col] == resources[i],] 
    for(r in 1:nrow(subset)) 
    { 
     color <- res.colors[((i-1)%%length(res.colors))+1] 
     start <- subset[r,start.col] 
     end <- subset[r,end.col] 
     rect(start,yBottom,end,yTop,col=color) 
    } 
    } 
    par(mar=op) # reset the plotting margins 
} 

Anwendungsbeispiel:

data <- read.table(text= 
'"person","n","start","end" 
"sam",6,0,6 
"greg",5,6,11 
"teacher",4,11,15 
"sam",4,15,19 
"greg",5,19,24 
"sally",5,24,29 
"greg",4,29,33 
"sam",3,33,36 
"sally",5,36,41 
"researcher",6,41,47 
"greg",6,47,53',sep=',',header=T) 

plotGantt(data, res.col='person',start.col='start',end.col='end', 
      res.colors=c('green','blue','brown','red','yellow')) 

Ergebnis:

enter image description here

+0

Diese Antwort erfüllte auch die von mir aufgeführten Parameter. Es sieht auch super aus. Danke für das Teilen, ein etwas anderer Ansatz. +1 –

+0

Auch danke für das Wort Gantt. Ich wusste nicht, wie es hieß. –

+1

@TylerRinker: Gern geschehen :). Allerdings habe ich den Code leicht geändert, um Platz für die Etiketten zu schaffen. – digEmAll