1

I need to display two datasets on the same faceted plots with ggplot2. The first dataset (dat) is to be shown as crosses like this:

enter image description here

While the second dataset (dat2) is to be shown as a color line. For an element of context, the second dataset is actually the Pareto frontier of the first set...

Both datasets (dat and dat2) look like this:

       modu mnc       eff
1 0.3080473   0 0.4420544
2 0.3110355   4 0.4633741
3 0.3334024   9 0.4653061

Here's my code so far:

library(ggplot2)

dat <- structure(list(modu = c(0.30947265625, 0.3094921875, 0.32958984375, 
0.33974609375, 0.33767578125, 0.3243359375, 0.33513671875, 0.3076171875, 
0.3203125, 0.3205078125, 0.3220703125, 0.28994140625, 0.31181640625, 
0.352421875, 0.31978515625, 0.29642578125, 0.34982421875, 0.3289453125, 
0.30802734375, 0.31185546875, 0.3472265625, 0.303828125, 0.32279296875, 
0.3165234375, 0.311328125, 0.33640625, 0.3140234375, 0.33515625, 
0.34314453125, 0.33869140625), mnc = c(15, 9, 6, 0, 10, 12, 14, 
9, 5, 11, 0, 15, 0, 2, 14, 13, 14, 17, 11, 12, 13, 6, 4, 0, 13, 
7, 10, 12, 7, 13), eff = c(0.492448979591836, 0.49687074829932, 
0.49421768707483, 0.478571428571428, 0.493537414965986, 0.493809523809524, 
0.49891156462585, 0.499319727891156, 0.495102040816327, 0.492285714285714, 
0.482312925170068, 0.498911564625851, 0.479931972789116, 0.492857142857143, 
0.495238095238095, 0.49891156462585, 0.49530612244898, 0.495850340136055, 
0.50156462585034, 0.496, 0.492897959183673, 0.487959183673469, 
0.495605442176871, 0.47795918367347, 0.501360544217687, 0.497850340136054, 
0.493496598639456, 0.493741496598639, 0.496734693877551, 0.499659863945578
)), .Names = c("modu", "mnc", "eff"), row.names = c(NA, 30L), class = "data.frame")

dat2 <- structure(list(modu = c(0.26541015625, 0.282734375, 0.28541015625, 
0.29216796875, 0.293671875), mnc = c(0.16, 0.28, 0.28, 0.28, 
0.28), eff = c(0.503877551020408, 0.504149659863946, 0.504625850340136, 
0.505714285714286, 0.508503401360544)), .Names = c("modu", "mnc", 
"eff"), row.names = c(NA, 5L), class = "data.frame")

dat$modu = dat$modu
dat$mnc = dat$mnc*50
dat$eff = dat$eff

dat2$modu = dat2$modu
dat2$mnc = dat2$mnc*50
dat2$eff = dat2$eff

res <- do.call(rbind, combn(1:3, 2, function(ii)
        cbind(setNames(dat[,c(ii, setdiff(1:3, ii))], c("x", "y")),
              var=paste(names(dat)[ii], collapse="/")), simplify=F))

ggplot(res, aes(x=x, y=y))+ geom_point(shape=4) +
  facet_wrap(~ var, scales="free")

How should I go about doing this? Do I need to add a layer? If so, how to do this in a faceted plot?

Thanks!

Lucien S.
  • 5,123
  • 10
  • 52
  • 88
  • You can add layers to faceted plots just the same as to unfaceted plots. Hard to say exactly how without seeing some data. – Heroka Sep 23 '15 at 19:22
  • Is there any way to add the data to your question using `dput()`? Linked data can break. – Heroka Sep 23 '15 at 19:26
  • I've never done this, I'm on it! – Lucien S. Sep 23 '15 at 19:27
  • 1
    This might be useful: how to create a [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). You can use dput(head(your_data,30)) if it's very large. – Heroka Sep 23 '15 at 19:28
  • Alright, this should work! – Lucien S. Sep 23 '15 at 19:34
  • Well done! One more step: between what and what should the coloured line be? – Heroka Sep 23 '15 at 19:36
  • Oh yes, I see... hmm... That's actually less trivial than I thought. So from the first to last row without going back to the first. Like the second example here: http://oco-carbon.com/metrics/find-pareto-frontiers-in-python/ – Lucien S. Sep 23 '15 at 19:41
  • 2
    As I'm currently procrastinating other things and you seem proficient in R, I think you can do this. Adding a line becomes then as simple as +geom_line(new_data, aes(x=xvar,y=var)). – Heroka Sep 23 '15 at 19:47
  • With "ggplot(res, aes(x=x, y=y)) + geom_point(shape=4) + geom_line(dat2, aes(x=x, y=y)) + facet_wrap(~ var, scales="free")" I get this error "ggplot2 doesn't know how to deal with data of class uneval" – Lucien S. Sep 23 '15 at 20:06
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/90473/discussion-between-heroka-and-rodolphe). – Heroka Sep 23 '15 at 20:19
  • 2
    I think you need data = dat2 in the second term - the error is thrown because you just put +geom_line(dat2... – CMichael Sep 23 '15 at 20:20

1 Answers1

2

Here's one way:

pts <- do.call(rbind, combn(1:3, 2, function(ii)
  cbind(setNames(dat[,c(ii, setdiff(1:3, ii))], c("x", "y")),
        var=paste(names(dat)[ii], collapse="/")), simplify=F))
lns <- do.call(rbind, combn(1:3, 2, function(ii)
  cbind(setNames(dat2[,c(ii, setdiff(1:3, ii))], c("x", "y")),
        var=paste(names(dat2)[ii], collapse="/")), simplify=F))
gg.df <- rbind(cbind(geom="pt",pts),cbind(geom="ln",lns))
ggplot(gg.df,aes(x,y)) +
  geom_point(data=gg.df[gg.df$geom=="pt",], shape=4)+
  geom_path(data=gg.df[gg.df$geom=="ln",], color="red")+
  facet_wrap(~var, scales="free")

The basic idea is to create separate data.frames for the points and the lines, then bind them together row-wise with an extra column (geom) indicating which geometry the data goes with. Then we plot the points based on the subset of gg.df with geom=="pt" and similarly with the lines.

The result isn't very interesting with your limited example, but this seems (??) to be what you want. Notice the use of geom_path(...) rather than geom_line(...). The latter orders the x-values before plotting.

jlhoward
  • 58,004
  • 7
  • 97
  • 140