R functions are first-class objects (of the class “function”, of course), meaning that they can be used for the most part just like other objects. This is seen in the syntax of function creation:
assigning function to g -> returns input + 1:
g <- function(x) {
return(x+1)
}
Here, function() is a built-in R function whose job is to create functions! On the right-hand side, there are really two arguments to function(): The first is the formal argument list for the function we’re creating—here, just x—and the second is the body of that function—here, just the single statement return(x+1). That second argument must be of class “expression”. So, the point is that the right-hand side creates a function object, which is then assigned to g.
These two arguments to function() can later be accessed via the R functions formals() and body(), as follows:
formals(g)
$x
-> formals allow us to see the expected argumetns/function inputs
body(g)
{
return(x + 1)
}
the body functions shows us what is happening with our input -> the actual function
Recall that when using R in interactive mode, simply typing the name of an object results in printing that object to the screen. Functions are no exception, since they are objects just like anything else.
g
function(x) {
return(x+1)
}
printing g results in the full funtion declaration to be shown
Create a function h and simulate a similar case scenario to the one shown above.
# declare function
h <- function(x)
{
return(x * (0.5* x))
}
# show h's body
body(h)
{
return(x * (0.5 * x))
}
# requried arguments
formals(h)
$x
# run h
h(5)
[1] 12.5
if you’re using a function that you wrote but which you’ve forgotten the details of. Printing out a function is also useful if you are not quite sure what an R library function does. By looking at the code, you may understand it better. For example, if you are not sure as to the exact behavior of the graphics function abline(), you could browse through its code to better understand how to use it.
# method 1
body(abline)
{
int_abline <- function(a, b, h, v, untf, col = par("col"),
lty = par("lty"), lwd = par("lwd"), ...) .External.graphics(C_abline,
a, b, h, v, untf, col, lty, lwd, ...)
if (!is.null(reg)) {
if (!is.null(a))
warning("'a' is overridden by 'reg'")
a <- reg
}
if (is.object(a) || is.list(a)) {
p <- length(coefa <- as.vector(coef(a)))
if (p > 2)
warning(gettextf("only using the first two of %d regression coefficients",
p), domain = NA)
islm <- inherits(a, "lm")
noInt <- if (islm)
!as.logical(attr(stats::terms(a), "intercept"))
else p == 1
if (noInt) {
a <- 0
b <- coefa[1L]
}
else {
a <- coefa[1L]
b <- if (p >= 2)
coefa[2L]
else 0
}
}
if (!is.null(coef)) {
if (!is.null(a))
warning("'a' and 'b' are overridden by 'coef'")
a <- coef[1L]
b <- coef[2L]
}
int_abline(a = a, b = b, h = h, v = v, untf = untf, ...)
invisible()
}
# method 2
print(abline)
function (a = NULL, b = NULL, h = NULL, v = NULL, reg = NULL,
coef = NULL, untf = FALSE, ...)
{
int_abline <- function(a, b, h, v, untf, col = par("col"),
lty = par("lty"), lwd = par("lwd"), ...) .External.graphics(C_abline,
a, b, h, v, untf, col, lty, lwd, ...)
if (!is.null(reg)) {
if (!is.null(a))
warning("'a' is overridden by 'reg'")
a <- reg
}
if (is.object(a) || is.list(a)) {
p <- length(coefa <- as.vector(coef(a)))
if (p > 2)
warning(gettextf("only using the first two of %d regression coefficients",
p), domain = NA)
islm <- inherits(a, "lm")
noInt <- if (islm)
!as.logical(attr(stats::terms(a), "intercept"))
else p == 1
if (noInt) {
a <- 0
b <- coefa[1L]
}
else {
a <- coefa[1L]
b <- if (p >= 2)
coefa[2L]
else 0
}
}
if (!is.null(coef)) {
if (!is.null(a))
warning("'a' and 'b' are overridden by 'coef'")
a <- coef[1L]
b <- coef[2L]
}
int_abline(a = a, b = b, h = h, v = v, untf = untf, ...)
invisible()
}
<bytecode: 0x00000238ed481d08>
<environment: namespace:graphics>
abline
function (a = NULL, b = NULL, h = NULL, v = NULL, reg = NULL,
coef = NULL, untf = FALSE, ...)
{
int_abline <- function(a, b, h, v, untf, col = par("col"),
lty = par("lty"), lwd = par("lwd"), ...) .External.graphics(C_abline,
a, b, h, v, untf, col, lty, lwd, ...)
if (!is.null(reg)) {
if (!is.null(a))
warning("'a' is overridden by 'reg'")
a <- reg
}
if (is.object(a) || is.list(a)) {
p <- length(coefa <- as.vector(coef(a)))
if (p > 2)
warning(gettextf("only using the first two of %d regression coefficients",
p), domain = NA)
islm <- inherits(a, "lm")
noInt <- if (islm)
!as.logical(attr(stats::terms(a), "intercept"))
else p == 1
if (noInt) {
a <- 0
b <- coefa[1L]
}
else {
a <- coefa[1L]
b <- if (p >= 2)
coefa[2L]
else 0
}
}
if (!is.null(coef)) {
if (!is.null(a))
warning("'a' and 'b' are overridden by 'coef'")
a <- coef[1L]
b <- coef[2L]
}
int_abline(a = a, b = b, h = h, v = v, untf = untf, ...)
invisible()
}
<bytecode: 0x00000238ed481d08>
<environment: namespace:graphics>