2013-04-17 3 views
2

Моих данных выглядят как в этом примере:Как указать факторы ggplot с горизонтальной линией и текстом

dataExample<-data.frame(Time=seq(1:10), 
     Data1=runif(10,5.3,7.5), 
     Data2=runif(10,4.3,6.5), 
     Application=c("Substance1","Substance1","Substance1", 
     "Substance1","Substance2","Substance2","Substance2", 
     "Substance2","Substance1","Substance1")) 
     dataExample 

      Time Data1 Data2 Application 
     1  1 6.511573 5.385265 Substance1 
     2  2 5.870173 4.512775 Substance1 
     3  3 6.822132 5.109790 Substance1 
     4  4 5.940528 6.281412 Substance1 
     5  5 7.269394 4.680380 Substance2 
     6  6 6.122454 6.015899 Substance2 
     7  7 5.660429 6.113362 Substance2 
     8  8 6.649749 4.344978 Substance2 
     9  9 7.252656 4.764667 Substance1 
     10 10 7.204440 5.835590 Substance1 

Я хотел бы указать, в какое время было применено любое вещество, которое отличается от dataExample$Application[1].

Здесь я покажу вам, как я это воспринимаю, но я предполагаю, что есть намного более простой способ сделать это с помощью ggplot.

library(reshape2) 
library(ggplot) 

plotDataExample<-function(DataFrame){ 
    longDF<-melt(DataFrame,id.vars=c("Time","Application")) 
    p=ggplot(longDF,aes(Time,value,color=variable))+geom_line() 

    maxValue=max(longDF$value) 
    minValue=min(longDF$value) 

    yAppLine=maxValue+((maxValue-minValue)/20) 
    xAppLine1=min(longDF$Time[which(longDF$Application!=longDF$Application[1])]) 
    xAppLine2=max(longDF$Time[which(longDF$Application!=longDF$Application[1])]) 
    lineData=data.frame(x=c(xAppLine1,xAppLine2),y=c(yAppLine,yAppLine)) 

    xAppText=xAppLine1+(xAppLine2-xAppLine1)/2 
    yAppText=yAppLine+((maxValue-minValue)/20) 
    appText=longDF$Application[which(longDF$Application!=longDF$Application[1])[1]] 
    textData=data.frame(x=xAppText,y=yAppText,appText=appText) 

    p=p+geom_line(data=lineData,aes(x=x, y=y),color="black") 
    p=p+geom_text(data=textData,aes(x=x,y=y,label = appText),color="black") 
    return(p) 
} 
plotDataExample(dataExample) 

enter image description here

Вопрос: Знаете ли вы, лучший способ получить такой же результат, так что я мог бы указать более одного фактора (например, Substance3, Substance4 ...).

+3

Наверняка вы имеете в виду Substance3, Substance4 ...? Учтите включить в свой пример больше веществ? –

+0

В ваших данных есть вероятность того, что Substance1 и Substance2 меняются более одного раза? –

+0

'dataExample <-data.frame (Time = seq (1:10), Data1 = runif (10,5.3,7.5), Data2 = runif (10,4.3,6.5), Application = c (" Substance1 " , «Вещество2», «Вещество2», «Вещество2», «Вещество2»)) – new2R

ответ

1

Во-первых, сделаны новые данные образца, чтобы иметь более 2 уровней и дважды повторяться Substance2.

dataExample<-data.frame(Time=seq(1:10), 
         Data1=runif(10,5.3,7.5), 
         Data2=runif(10,4.3,6.5), 
         Application=c("Substance1","Substance1","Substance2", 
             "Substance2","Substance1","Substance1","Substance2", 
             "Substance2","Substance3","Substance3")) 

Не делал это как функцию для отображения каждого шага.

Добавить новый столбец groups в исходный фрейм данных - это содержит идентификатор для группировки Applications - если вещество изменяется, то формируется новая группа.

dataExample$groups<-c(cumsum(c(1,tail(dataExample$Application,n=-1)!=head(dataExample$Application,n=-1)))) 

Преобразование данных длинного формата для строк данных.

longDF<-melt(dataExample,id.vars=c("Time","Application","groups")) 

Рассчитать позиции по Веществам. Используемая функция ddply() из библиотеки plyr. Для расчета используются только данные, которые отличаются от первого значения Application (это subset()). Затем для группировки данных используются Application и groups. Расчетное начальное, среднее и конечное положения по оси x и y, принятое как максимальное value +0.3.

library(plyr)  
lineData<-ddply(subset(dataExample,Application != dataExample$Application[1]), 
     .(Application,groups), 
       summarise,minT=min(Time),maxT=max(Time), 
       meanT=mean(Time),ypos=max(longDF$value)+0.3) 

Теперь участок данных longDF с ggplot() и geom_line() и добавлять сегменты выше участка с geom_segment() и текст с annotate() использованием нового кадра lineData данных.

ggplot(longDF,aes(Time,value,color=variable))+geom_line()+ 
    geom_segment(data=lineData,aes(x=minT,xend=maxT,y=ypos,yend=ypos),inherit.aes=FALSE)+ 
    annotate("text",x=lineData$meanT,y=lineData$ypos+0.1,label=lineData$Application) 

enter image description here

+0

Спасибо, этот код именно то, что я искал. Но когда я делаю это как функцию, R говорит: «Ошибка в eval (expr, envir, enc): объект« longDF »не найден». Знаете ли вы, что я делаю неправильно? – new2R

+0

См. Это [вопрос о SO] (http://stackoverflow.com/questions/10659133/local-variables-within-aes/10662937#10662937) –

Смежные вопросы