I want to plot polynomial functions of high degrees with given coefficiants. I created this function 'f_erzeuger' in order to write a polynomial function 'f' to be able to plot it with ggplot2 and stat_function(fun = f). 'coef' is a vector of coefficiants for the ploynomial function.
f_erzeuger <- function(coef) {
f <- function(x) {
x_vec <- c(1, x, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10)
d <- length(coef) - 1 # degree of the polynomial
sum(coef * x_vec[1:(d 1)])
}
f
}
However ggplot2 is not able to plot this curve, propably because the function doesn't actually calculate a function term.
f <- f_erzeuger(c(4, 5, 2))
ggplot(data.frame(x = c(-50, 50)), aes(x = x))
stat_function(fun = f, color = "blue")
stat_function(fun = function(x){3 5*x 2*x^2}, color = "red")
The created function f is beeing plottet as a line even though f works as a function.
Does anyone have an idea how to fix this? Thank you in advance!
CodePudding user response:
The problem is that your function is not vectorized. Running ?stat_function and looking at the documentation for fun:
fun: Function to use. Either 1) an anonymous function in the base or rlang formula syntax (seerlang::as_function()) or 2) a quoted or character name referencing a function; see examples. Must be vectorised.
To make the function vectorized, we need to make sure that, for example, f(c(0, 1)) will return c(f(0), f(1)). Note that one issue in your function is the line where you define x_vec = c(1, x, ...). This wouldn't work if x were a vector with more than one element.
There are many ways to vectorize your function. I will do it using the tidyverse (mainly purrr::map()).
f_erzeuger = function(coef) {
function(xvals) {
d = length(coef)
map_dbl(xvals, function(x) {
x_vec = x ^ (0:(d - 1))
sum(coef * x_vec)
})
}
}
The changes made to this function:
- Most importantly, the function is now vectorized.
- Instead of defining
x_vecexplicitly to degree 10, we can leverage the fact that^in R is vectorized (sox^(0:2)is the same asc(1, x, x^2)). - We can return the function directly inside
f_erzeuger()instead of definingfand then returning it.
Now things will work as expected:

CodePudding user response:
Try curve.
f <- f_erzeuger(c(4, 5, 2))
curve(Vectorize(f)(x), -50, 50, col='#c55d0d')


