使用geom_line为因子的子集绘制线条

时间:2014-06-19 17:58:13

标签: r ggplot2

我试图根据数据框的一部分绘制单独的行,但是当我这样做时,会为不想连接的点绘制线条。

使用geom_segment手动绘制它们我得到了我之后的内容(减去正确的图例):

enter image description here

但是当我使用geom_line时,它应该允许我将代码用于不同的图形并添加正确的图例(我希望),我能做的最好的就是:

enter image description here

我的数据框(df):

df <- read.table(text='Treatment           Function  Time N    Rel_abund           sd           se           ci
1      Start     "Methanogenesis" Start 3 1.983614e-04 3.839642e-05 2.216818e-05 9.538199e-05
2      Start  "Methane oxidation" Start 3 1.245265e-04 2.275417e-05 1.313712e-05 5.652448e-05
3      Start "Sulphate Reduction" Start 3 3.693332e-05 1.247878e-05 7.204626e-06 3.099900e-05
4  "1 x Flood"     "Methanogenesis"   End 3 1.673369e-04 1.043482e-05 6.024546e-06 2.592153e-05
5  "1 x Flood"  "Methane oxidation"   End 3 1.269306e-04 2.938948e-05 1.696803e-05 7.300753e-05
6  "1 x Flood" "Sulphate Reduction"   End 3 3.742168e-05 2.187629e-06 1.263028e-06 5.434372e-06
7 "3 x Floods"     "Methanogenesis"   End 3 2.135845e-04 3.762486e-05 2.172272e-05 9.346534e-05
8 "3 x Floods"  "Methane oxidation"   End 3 9.097189e-05 1.192464e-05 6.884691e-06 2.962244e-05
9 "3 x Floods" "Sulphate Reduction"   End 3 8.513220e-05 2.271764e-05 1.311603e-05 5.643374e-05')

我的代码:

ggplot(df, aes(x=Time, y=Rel_abund,col=Function))+geom_point(size=2,position=position_dodge(.1))+
  geom_errorbar(aes(ymin=Rel_abund-se,ymax=Rel_abund+se),width=0.075,position=position_dodge(.1))+
  geom_line(aes(group=Function),position=position_dodge(.1))+

我可以看到它正在做什么,因为它连接了每个函数的所有实例,但是当我在相应的行中创建两个带有NA的新列时,它仍然连接所有NA事件

最终,我想要一个看起来与我的顶级图形类似的图表,其中的图例包含不同处理的差异线类型(1 x Flood,3 x Floods),并且使用的代码可以可以轻松应用或修改其他数据集。

提前致谢!

2 个答案:

答案 0 :(得分:1)

不幸的是,我不知道除了重新划分你的数据之外还要做其他事情。这是我要做的转变

ld<-do.call(rbind, lapply(split(df, df$Function), function(x) {
    s <- x$Time=="Start"; 
    ids <- paste(x$Function[!s], 1:sum(!s)) 
    cols <- c("Time","Rel_abund", "Function")
    suppressWarnings(rbind(
        cbind(x[s, cols], Treatment=x$Treatment[!s], id=ids), 
        cbind(x[!s, c(cols, "Treatment")], id=ids)
    ))
}))

哪个会产生

    Time    Rel_abund           Function  Treatment                   id
1  Start 1.245265e-04  Methane oxidation  1 x Flood  Methane oxidation 1
2  Start 1.245265e-04  Methane oxidation 3 x Floods  Methane oxidation 2
3    End 1.269306e-04  Methane oxidation  1 x Flood  Methane oxidation 1
4    End 9.097189e-05  Methane oxidation 3 x Floods  Methane oxidation 2
5  Start 1.983614e-04     Methanogenesis  1 x Flood     Methanogenesis 1
6  Start 1.983614e-04     Methanogenesis 3 x Floods     Methanogenesis 2
7    End 1.673369e-04     Methanogenesis  1 x Flood     Methanogenesis 1
8    End 2.135845e-04     Methanogenesis 3 x Floods     Methanogenesis 2
9  Start 3.693332e-05 Sulphate Reduction  1 x Flood Sulphate Reduction 1
10 Start 3.693332e-05 Sulphate Reduction 3 x Floods Sulphate Reduction 2
11   End 3.742168e-05 Sulphate Reduction  1 x Flood Sulphate Reduction 1
12   End 8.513220e-05 Sulphate Reduction 3 x Floods Sulphate Reduction 2

因此我们为每个功能/治疗组合复制了Start值。然后我们保留了两个End值。我们还更新了Start值的处理,以便我们可以根据它进行设计。最后我们添加了一个ID,因此qqplot将知道要连接的起点/终点。它可能不是最漂亮的转变,但它可以完成工作。

现在我们可以用

画出情节
library(ggplot2)
ggplot(df, aes(x=Time, y=Rel_abund, col=Function))+
    geom_point(size=2,position=position_dodge(.1))+
    geom_errorbar(aes(ymin=Rel_abund-se, ymax=Rel_abund+se), 
        width=0.075, position=position_dodge(.1))+
    geom_line(data=ld, aes(group=id, lty=Treatment),
        position=position_dodge(.1)
)

请注意,我们使用原始data.frame作为第一个新命令,并仅为geom_line()指定我们的特殊数据集。这会给我们带来

enter image description here

这非常接近你的第一张照片。

答案 1 :(得分:1)

这是一种使用geom_segment(...)并且不需要重新整形数据集的方法,尽管我必须承认它有点像黑客。

df$Start <- merge(df,df[df$Time=="Start",c(3,5)],by="Time")$Rel_abund.y
df$Time  <- factor(df$Time,levels=c("Start","End"))

library(ggplot2)
ggplot(df, aes(x=Time, y=Rel_abund,col=Function))+
  geom_point(size=2,position=position_dodge(.1))+
  geom_errorbar(aes(ymin=Rel_abund-se,ymax=Rel_abund+se),width=0.075,position=position_dodge(.1))+
  geom_segment(data=df[df$Time!="Start",], 
               aes(x=1, xend=2+(as.numeric(Function)-2)*0.04, y=Start, yend=Rel_abund, color=Function , linetype=Treatment),
               position=position_dodge(0.1))

所以我们在这里添加一个额外的列Startdf,其中包含Rel_abund的起始值 - 换句话说,我们为df[df$Time=="Start",]$Rel_abund每个值复制Function {1}}。使用merge(...)执行此操作只是保证为Function的不同值正确分配值。从那里可以直接使用geom_segment(...),除了一件事:你想要躲避x值。

躲避geom_segment(...)的问题是position_dodge(...)仅适用于x美学,而不是xend。因此,上面的代码通过将0.04*(as.numeric(Function)-2)添加到xend来解决这个问题。