How to deal with zero in log plot
<h1>The Problem</h1>

<p>I have data that I would like to plot in a line-graph with a log-scale on the y-axis using ggplot2. Unfortunately, some of my values go all the way down to zero. The data represents relative occurences of a feature in dependence of some parameters. The value zero occurs when that feature is not observed in a sample, which means that it occurs very seldomly, or indeed never. These zero values cause a problem in the log plot.</p>

<p>The following code illustrates the problem on a simplified data set. In reality the data set consists of more points, so the curve looks smoother, and also more values for the parameter <code>p</code>.</p>

<pre><code>library(ggplot2)

dat &lt;- data.frame(x=rep(c(0, 1, 2, 3), 2),
                  y=c(1e0, 1e-1, 1e-4, 0,
                      1e-1, 1e-3, 0, 0),
                  p=c(rep('a', 4), rep('b', 4)))
qplot(data=dat, x=x, y=y, colour=p, log="y", geom=c("line", "point"))
</code></pre>

<p>Given the data above, we would expect two lines, the first one should have three finite points on a log plot, the second one should have only two finite points on a log plot.</p>

<p><a href="https://i.stack.imgur.com/kOcS0m.png" rel="noreferrer"><img src="https://i.stack.imgur.com/kOcS0m.png" alt="Misleading plot"></a></p>

<p>However, as you can see this produces a very misleading plot. It looks like the blue and red line are both converging to a value between 1e-4 and 1e-3. The reason is that <code>log(0)</code> gives <code>-Inf</code>, which ggplot just puts on the lower axis.</p>

<h1>My Question</h1>

<p>What's the best way to deal with this in R with ggplot2? By <em>best</em> I mean in terms of efficiency, and being ideomatic R (I'm fairly new to R).</p>

<p>The plot should indicate that these curves go down to "very small" after x=2 (red), or x=1 (blue), respectively. Ideally, with a vertical line downwards from the last finite point. What I mean by that is demonstrated in the following.</p>

<h1>My Attempt</h1>

<p>Here I'll describe what I've come up with. However, given that I'm fairly new to R, I suspect that there might a much better way.</p>

<pre><code>library(ggplot2)
library(scales)

dat &lt;- data.frame(x=rep(c(0, 1, 2, 3), 2),
                  y=c(1e0, 1e-1, 1e-4, 0,
                      1e-1, 1e-3, 0, 0),
                  p=c(rep('a', 4), rep('b', 4)))
</code></pre>

<p>Same data as above.</p>

<p>Now, I'm going through each unique parameter <code>p</code>, find the x coordinate of the last finite point, and assign it to the x coordinates of all points where y is zero. That is to achieve a vertical line.</p>

<pre><code>for (p in unique(dat$p)) {
    dat$x[dat$p == p &amp; dat$y == 0] &lt;- dat$x[head(which(dat$p == p &amp; dat$y == 0), 1) - 1]
}
</code></pre>

<p>At this point the plot looks as follows.</p>

<p><a href="https://i.stack.imgur.com/wrSH3m.png" rel="noreferrer"><img src="https://i.stack.imgur.com/wrSH3m.png" alt="Vertical lines and points"></a></p>

<p>The vertical lines are there. However, there are also points. These are misleading as they indicate that there was an actual data point there, which is not true.</p>

<p>To remove the points I duplicate the y data (seems wasteful), let's call it <code>yp</code>, and replace zero by <code>NA</code>. Then I use that new <code>yp</code> as the y aesthetics for <code>geom_point</code>.</p>

<pre><code>dat$yp &lt;- dat$y
dat$yp[dat$y == 0] &lt;- NA

ggplot(dat, aes(x=x, y=y, colour=p)) +
    geom_line() +
    geom_point(aes(y=dat$yp)) +
    scale_y_continuous(trans=log10_trans(),
                       breaks = trans_breaks("log10", function(x) 10^x),
                       labels = trans_format("log10", math_format(10^.x)))
</code></pre>

<p>Where I've used <code>ggplot</code> instead of <code>qplot</code> so that I can give different aesthetics to <code>geom_line</code> and <code>geom_point</code>.</p>

<p>Finally, the plot looks like this.</p>

<p><a href="https://i.stack.imgur.com/3cL4Am.png" rel="noreferrer"><img src="https://i.stack.imgur.com/3cL4Am.png" alt="Final Plot"></a></p>

<p>What is the <em>right</em> way to do this?</p>