I am attempting to plot this function over the values 0 - 1:
dweird <- function(x){
if (x< 0){return(0)}
if (x> 1){return(0)}
if (x >= 0 & x < (1/3)) {return((1))}
if (x >= (1/3) & x < (2/3)){return(3/2)}
if (x >= (2/3) & x <= 1){return((1/2))}
}
and here is the code that I'm using
library(ggplot2)
ggplot(data.frame(x=c(0, 1)), aes(x)) +
stat_function(fun=function(x) dweird(x), linetype="dotted")
But this returns the error message
Warning message: In if (x >= 0 & x < (1/3)) { : the condition has length > 1 and only the first element will be used
To be clear, the function should plot one straight line at y= 1 from 0-1/3, another at y=1.5 from 1/3-2/3, and another line at 1/2 from 2/3 to 1.
Any ideas why I'm getting that error message?
You need to vectorize your function. ggplot doesn't expect to evaluate it one point at a time. The lazy way is to use vectorize
dweird_v_lazy = Vectorize(dweird)
but the better way is to just code it that way in the first place:
dweird_v = function(x) {
ifelse(x < 0, 0,
ifelse(x < 1/3, 1,
ifelse(x < 2/3, 3/2,
ifelse(x < 1, 1/2, 0))))
}
# or, more concisely with `cut`:
dweird_cut = function(x) {
as.numeric(as.character(
cut(x,
breaks = c(-Inf, 0, 1/3, 2/3, 1, Inf),
labels = c(0, 1, 1.5, .5, 0)
)
))
}
Then this will work just fine:
x = seq(-.2, 1.2, length.out = 15)
dweird_v(x)
[1] 0.0 0.0 0.0 1.0 1.0 1.0 1.5 1.5 1.5 0.5 0.5 0.5 0.0 0.0 0.0
As will your plot:
library(ggplot2)
ggplot(data.frame(x=c(0, 1)), aes(x)) +
stat_function(fun= dweird_v, linetype="dotted")
Note that when you're passing a single function to stat_function
, you don't have to turn it into an anonymous function, you can just tell it the name of your function.
您需要“矢量化”您的功能:
dweird <- Vectorize(dweird)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.