8

I have discreet data that looks like this:

height <- c(1,2,3,4,5,6,7,8)
weight <- c(100,200,300,400,500,600,700,800)
person <- c("Jack","Jim","Jill","Tess","Jack","Jim","Jill","Tess")
set <- c(1,1,1,1,2,2,2,2)
dat <- data.frame(set,person,height,weight)

I'm trying to plot a graph with same x-axis(person), and 2 different y-axis (weight and height). All the examples, I find is trying to plot the secondary axis (sec_axis), or discreet data using base plots. Is there an easy way to use sec_axis for discreet data on ggplot2? Edit: Someone in the comments suggested I try the suggested reply. However, I run into this error now

Here is my current code:

p1 <- ggplot(data = dat, aes(x = person, y = weight)) + 
  geom_point(color = "red") + facet_wrap(~set, scales="free") 
p2 <- p1 + scale_y_continuous("height",sec_axis(~.*1.2, name="height"))
p2

I get the error: Error in x < range[1] : 
  comparison (3) is possible only for atomic and list types

Alternately, now I have modified the example to match this example posted.

p <- ggplot(dat, aes(x = person))
p <- p + geom_line(aes(y = height, colour = "Height"))

# adding the relative weight data, transformed to match roughly the range of the height
p <- p + geom_line(aes(y = weight/100, colour = "Weight"))

# now adding the secondary axis, following the example in the help file ?scale_y_continuous
# and, very important, reverting the above transformation
p <- p + scale_y_continuous(sec.axis = sec_axis(~.*100, name = "Relative weight [%]"))

# modifying colours and theme options
p <- p + scale_colour_manual(values = c("blue", "red"))
p <- p + labs(y = "Height [inches]",
              x = "Person",
              colour = "Parameter")
p <- p + theme(legend.position = c(0.8, 0.9))+ facet_wrap(~set, scales="free") 
p

I get an error that says

"geom_path: Each group consists of only one observation. Do you need to 
 adjust the group aesthetic?"

I get the template, but no points get plotted

Share
  • 395
  • 7
  • 19
  • Those are continuous data (numbers), not discrete (categories). – Brian Sep 05 '17 at 00:22
  • I realized I linked the incorrect source. I have linked the correct one and updated my answer with the error, if I use it – Share Sep 05 '17 at 00:43
  • Add `sec.axis = ` in front of your `sec_axis(...)`. Without naming the argument explicitly, it defaulted to the 2nd argument in `scale_y_continuous()`, & `breaks = sec_axis(~.*1.2, name="height")` triggers that error because it made no sense in context. – Z.Lin Sep 05 '17 at 01:31
  • Like this `p1 + scale_y_continuous("height", sec_axis(sec.axis= ~.*1.2, name="height"))` ? This throws me an error – Share Sep 05 '17 at 01:39
  • As far as I know `ggplot2` does not support independent secondary axis. All secondary axes must be based on a one-to-one transformation of the primary axes. – LVG77 Sep 05 '17 at 02:55
  • I think that was the case some years ago, but now they seem to have sec_axis, that seems to do the job for others. Not able to get it work for me. – Share Sep 05 '17 at 03:00

1 Answers1

0

R function arguments are fed in by position if argument names are not specified explicitly. As mentioned by @Z.Lin in the comments, you need sec.axis= before your sec_axis function to indicate that you are feeding this function into the sec.axis argument of scale_y_continuous. If you don't do that, it will be fed into the second argument of scale_y_continuous, which by default, is breaks=. The error message is thus related to you not feeding in an acceptable data type for the breaks argument:

p1 <- ggplot(data = dat, aes(x = person, y = weight)) + 
  geom_point(color = "red") + facet_wrap(~set, scales="free") 
p2 <- p1 + scale_y_continuous("weight", sec.axis = sec_axis(~.*1.2, name="height"))
p2

![enter image description here

The first argument (name=) of scale_y_continuous is for the first y scale, where as the sec.axis= argument is for the second y scale. I changed your first y scale name to correct that.

acylam
  • 18,231
  • 5
  • 36
  • 45
  • But this does not seem to plot the weight and height. I need both the weight and height to be plotted on the same x-axis. – Share Sep 05 '17 at 03:32
  • @Ash It's just the label that's not specified correctly. See my edited answer. – acylam Sep 05 '17 at 03:37
  • No. I don't think you see my point. For each person, eg. In Set1, for Jack I should be seeing two points, one that corresponds to his height (say marked in red) and the other to his weight (say marked in black). The plot here instead is yielding a single points, perhaps a relationship between weight and height? That is not what I want. – Share Sep 05 '17 at 03:42
  • 2
    @Ash I see, you actually want two different y axes on the same plot. In this case, `sec.axis` is not the right solution, since it only allows for a second axis that is a linear transformation of the first axis. I think there are no good solutions with `ggplot2` because it is by design to discourage misrepresentation of data. See this discussion: https://stackoverflow.com/questions/3099219/plot-with-2-y-axes-one-y-axis-on-the-left-and-another-y-axis-on-the-right – acylam Sep 05 '17 at 04:48