My initial answer may not be what you really want, as it was pretty conditional. Here is a symbolic solution.
## use `"x"` as variable name ## taking polynomial coefficient vector `pc` ## can return a string, or an expression by further parsing (mandatory for `D`) f <- function (pc, expr = TRUE) { stringexpr <- paste("x", seq_along(pc) - 1, sep = " ^ ") stringexpr <- paste(stringexpr, pc, sep = " * ") stringexpr <- paste(stringexpr, collapse = " + ") if (expr) return(parse(text = stringexpr)) else return(stringexpr) } ## an example cubic polynomial with coefficients 0.1, 0.2, 0.3, 0.4 cubic <- f(pc = 1:4 / 10, TRUE) ## using R base `D` (requiring expression) dcubic <- D(cubic, name = "x") # 0.2 + 2 * x * 0.3 + 3 * x^2 * 0.4 ## using `Deriv::Deriv` library(Deriv) dcubic <- Deriv(cubic, x = "x", nderiv = 1L) # expression(0.2 + x * (0.6 + 1.2 * x)) Deriv(f(1:4 / 10, FALSE), x = "x", nderiv = 1L) ## use string, get string # [1] "0.2 + x * (0.6 + 1.2 * x)"
Of course, Deriv makes it easier to obtain higher order derivatives. We can just install nderiv . However, for D we must use recursion (see Examples ?D ).
Deriv(cubic, x = "x", nderiv = 2L) # expression(0.6 + 2.4 * x) Deriv(cubic, x = "x", nderiv = 3L) # expression(2.4) Deriv(cubic, x = "x", nderiv = 4L) # expression(0)
If we use an expression, we can evaluate the result later. For instance,
eval(cubic, envir = list(x = 1:4))
It follows from the above that we can complete the expression for the function. Using a function has several advantages, one of which is that we can build it using curve or plot.function .
fun <- function(x, expr) eval.parent(expr, n = 0L)
Please note: fun requires an expr expression in terms of x . If expr was defined in terms of y , for example, we need to define fun with function (y, expr) . Now use curve to plot cubic and dcubic on the range 0 < x < 5 :
curve(fun(x, cubic), from = 0, to = 5) ## colour "black" curve(fun(x, dcubic), add = TRUE, col = 2) ## colour "red"

The most convenient way is, of course, to define one fun function instead of the f + fun combination. Thus, we also do not need to worry about the consistency of the variable name used by f and fun .
FUN <- function (x, pc, nderiv = 0L) { ## check missing arguments if (missing(x) || missing(pc)) stop ("arguments missing with no default!") ## expression of polynomial stringexpr <- paste("x", seq_along(pc) - 1, sep = " ^ ") stringexpr <- paste(stringexpr, pc, sep = " * ") stringexpr <- paste(stringexpr, collapse = " + ") expr <- parse(text = stringexpr) ## taking derivatives dexpr <- Deriv::Deriv(expr, x = "x", nderiv = nderiv) ## evaluation val <- eval.parent(dexpr, n = 0L) ## note, if we take to many derivatives so that `dexpr` becomes constant ## `val` is free of `x` so it will only be of length 1 ## we need to repeat this constant to match `length(x)` if (length(val) == 1L) val <- rep.int(val, length(x)) ## now we return val }
Suppose we want to evaluate a cubic polynomial with coefficients pc <- c(0.1, 0.2, 0.3, 0.4) and its derivatives on x <- seq(0, 1, 0.2) , we can simply do:
FUN(x, pc)
Now the plot is also simple:
curve(FUN(x, pc), from = 0, to = 5) curve(FUN(x, pc, 1), from = 0, to = 5, add = TRUE, col = 2) curve(FUN(x, pc, 2), from = 0, to = 5, add = TRUE, col = 3) curve(FUN(x, pc, 3), from = 0, to = 5, add = TRUE, col = 4)
