1

I am trying to plot a graph of two functions (i.e., 2x + 1 and 3x - 0.5*x^2) on a same graph sheet, but with two different ranges (x<=3 and x>3, respectively). So far, I have defined two functions as the following:

# Define first function with given range
Line1 <- function(x) {
    if (x <= 3) {
        (3*x) + 1 } else {
    }       
}

# Define second function with given range
Line2 <- function(x) {
    if (x > 3) {
        2*x - (0.5*(x^2)) } else {
    }         
}

# Plot functions
ggplot(d,aes(x=x)) + stat_function(fun=rwrap(Line1,0,3),geom="line",col="blue") 
+ stat_function(fun=rwrap(Line2,3,5),geom="line",col="red")`

When I run the code, I get the following error messages:

Error: Discrete value supplied to continuous scale In addition:

Warning messages:
1: In if (x <= 3) { : the condition has length > 1 and only the first element will be used
2: In if (x > 3) { : the condition has length > 1 and only the first element will be used

I tried to troubleshoot it, but I am just lost at this point.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • Why is your code quoted? – Gregor Thomas Sep 01 '17 at 22:33
  • 3
    The problem is that you're functions aren't vectorized. They will work for a single value of `x` at at time, but `Line1(0:10)` won't work. Make it a single function with `ifelse` as the vectorized version of `if{}else{}`: `foo = function(x) ifelse(x <= 3, 3 * x + 1, 2 * x - 0.5 * x ^ 2)`. – Gregor Thomas Sep 01 '17 at 22:36
  • Sorry about the quotation, I made a mistake of copy and paste process. I understood your ifelse statement. However, how would I plot the lines with different colors? – user8550070 Sep 01 '17 at 22:42
  • I finally managed to plot it! Thank you guys! :) You guys are godsend! – user8550070 Sep 01 '17 at 22:52
  • 2
    Thanks for the edit, Lamia! I am a newbie :p – user8550070 Sep 01 '17 at 23:15
  • 1
    @Gregor You should post as an answer. Shame to see that nice explanation multi-line in the comments ;) – Nate Sep 02 '17 at 00:12

1 Answers1

0

The problem is that you're functions aren't vectorized. They will work for a single value of x at at time, but Line1(0:10) won't work.

Make it a single vectorized function with ifelse, the vectorized version of if{}else{}:

foo = function(x) {
    ifelse(x <= 3, 3 * x + 1, 2 * x - 0.5 * x ^ 2)
 }

You could break it down like this:

bar = function(x) 3 * x + 1
baz = function(x) 2 * x - 0.5 * x^2
foo = function(x) ifelse(x <= 3, bar(x), baz(x))

though of course you would want to use more meaningful names than these placeholders.

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294