17.2 Code

We can actually see the contents of a function by typing sd (with no ? and no parentheses). Sometimes we will see the function explicitly written out. Here is the code for sd.

Code
sd
function (x, na.rm = FALSE) 
sqrt(var(if (is.vector(x) || is.factor(x)) x else as.double(x), 
    na.rm = na.rm))
<bytecode: 0x55e4e24b9410>
<environment: namespace:stats>

The code for sd finds the square root of the variance of x.

17.2.1 Generic functions

If we try to look at the code for print, we’ll see this.

Code
print
standardGeneric for "print" defined from package "base"

function (x, ...) 
standardGeneric("print")
<environment: 0x55e4e2117780>
Methods may be defined for arguments: x
Use  showMethods(print)  for currently available ones.

All we see here is UseMethod("print") because print is a generic function that will use different code depending on whether we give it a data.frame, list or some other object. For example, if we give print a list, it will show each object in the list, each labeled with $nameoftheobject and separated by a blank line.

Code
mylist = list(x1 = 1:10, 
              x2 = 11:20, 
              x3 = 21:30, 
              x4 = 31:40, 
              x5 = 41:50, 
              x6 = 51:60, 
              x7 = 61:70)
is(mylist)
print(mylist)
[1] "list"   "vector"
$x1
 [1]  1  2  3  4  5  6  7  8  9 10

$x2
 [1] 11 12 13 14 15 16 17 18 19 20

$x3
 [1] 21 22 23 24 25 26 27 28 29 30

$x4
 [1] 31 32 33 34 35 36 37 38 39 40

$x5
 [1] 41 42 43 44 45 46 47 48 49 50

$x6
 [1] 51 52 53 54 55 56 57 58 59 60

$x7
 [1] 61 62 63 64 65 66 67 68 69 70

If this list were a data.frame object, it would show a table of data.

Code
my.df = as.data.frame(mylist)
is(my.df)
print(my.df)
[1] "data.frame" "list"       "oldClass"   "vector"    
   x1 x2 x3 x4 x5 x6 x7
1   1 11 21 31 41 51 61
2   2 12 22 32 42 52 62
3   3 13 23 33 43 53 63
4   4 14 24 34 44 54 64
5   5 15 25 35 45 55 65
6   6 16 26 36 46 56 66
7   7 17 27 37 47 57 67
8   8 18 28 38 48 58 68
9   9 19 29 39 49 59 69
10 10 20 30 40 50 60 70

If we have an lm object that is the result of fitting a linear regression to data using the function lm, print shows some basic information about the model.

Code
lm1 = lm(mpg  ~ wt, 
         data = mtcars)
is(lm1)
print(lm1)
[1] "lm"       "oldClass"

Call:
lm(formula = mpg ~ wt, data = mtcars)

Coefficients:
(Intercept)           wt  
     37.285       -5.344  

If we have a summary.lm object, print will give an output with coefficients, standard errors, t-statistics, p-values, the significance stars, \(R^2\), Adjusted \(R^2\), and so on

Code
lm1.summary = summary(lm1)
is(lm1.summary)
print(lm1.summary)
[1] "summary.lm"

Call:
lm(formula = mpg ~ wt, data = mtcars)

Residuals:
    Min      1Q  Median      3Q     Max 
-4.5432 -2.3647 -0.1252  1.4096  6.8727 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  37.2851     1.8776  19.858  < 2e-16 ***
wt           -5.3445     0.5591  -9.559 1.29e-10 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 3.046 on 30 degrees of freedom
Multiple R-squared:  0.7528,    Adjusted R-squared:  0.7446 
F-statistic: 91.38 on 1 and 30 DF,  p-value: 1.294e-10

17.2.2 methods

We can use methods to see what objects the function print has methods for.

Code
methods('print') %>% head(20)
 [1] "print,ANY-method"            "print,bayesglm-method"      
 [3] "print,bayespolr-method"      "print,diagonalMatrix-method"
 [5] "print,ggmultiplot-method"    "print,sparseMatrix-method"  
 [7] "print.aareg"                 "print.abbrev"               
 [9] "print.acf"                   "print.activeConcordance"    
[11] "print.ada"                   "print.AES"                  
[13] "print.all_vars"              "print.allFit"               
[15] "print.anova"                 "print.Anova"                
[17] "print.anova.gam"             "print.anova.lme"            
[19] "print.anova.loglm"           "print.any_vars"             

We are using head (also generic!) to only show the first 20 methods. There are actually several hundred!

Code
length(methods('print'))
[1] 854

Here are the methods that contain the character string lm as part of the name.

Code
grep('lm', 
     methods('print'), 
     value = TRUE)
 [1] "print,bayesglm-method"  "print.anova.lme"        "print.anova.loglm"     
 [4] "print.gelman.diag"      "print.glm"              "print.glm.dose"        
 [7] "print.intervals.lme"    "print.intervals.lmList" "print.lm"              
[10] "print.lme"              "print.lmList"           "print.loglm"           
[13] "print.ranef.lme"        "print.ridgelm"          "print.rlm"             
[16] "print.simulate.lme"     "print.summary.glm"      "print.summary.lm"      
[19] "print.summary.lme"      "print.summary.lmList"   "print.summary.loglm"   
[22] "print.summary.rlm"      "print.VarCorr.lme"     

17.2.3 getAnywhere

If we want to see the code for one of these methods, we can use getAnywhere. Let’s see the code for print.lm and print.summary.lm. Since the output of print(summary.lm) above is much more detailed than print(lm1), it is not surprising that the code for print.summary.lm is much more involved than the code for print.lm.

Code
getAnywhere('print.lm')
A single object matching 'print.lm' was found
It was found in the following places
  registered S3 method for print from namespace stats
  namespace:stats
with value

function (x, digits = max(3L, getOption("digits") - 3L), ...) 
{
    cat("\nCall:\n", paste(deparse(x$call), sep = "\n", collapse = "\n"), 
        "\n\n", sep = "")
    if (length(coef(x))) {
        cat("Coefficients:\n")
        print.default(format(coef(x), digits = digits), print.gap = 2L, 
            quote = FALSE)
    }
    else cat("No coefficients\n")
    cat("\n")
    invisible(x)
}
<bytecode: 0x55e4ecb638d8>
<environment: namespace:stats>
Code
getAnywhere('print.summary.lm')
A single object matching 'print.summary.lm' was found
It was found in the following places
  registered S3 method for print from namespace stats
  namespace:stats
with value

function (x, digits = max(3L, getOption("digits") - 3L), symbolic.cor = x$symbolic.cor, 
    signif.stars = getOption("show.signif.stars"), ...) 
{
    cat("\nCall:\n", paste(deparse(x$call), sep = "\n", collapse = "\n"), 
        "\n\n", sep = "")
    resid <- x$residuals
    df <- x$df
    rdf <- df[2L]
    cat(if (!is.null(x$weights) && diff(range(x$weights))) 
        "Weighted ", "Residuals:\n", sep = "")
    if (rdf > 5L) {
        nam <- c("Min", "1Q", "Median", "3Q", "Max")
        rq <- if (length(dim(resid)) == 2L) 
            structure(apply(t(resid), 1L, quantile), dimnames = list(nam, 
                dimnames(resid)[[2L]]))
        else {
            zz <- zapsmall(quantile(resid), digits + 1L)
            structure(zz, names = nam)
        }
        print(rq, digits = digits, ...)
    }
    else if (rdf > 0L) {
        print(resid, digits = digits, ...)
    }
    else {
        cat("ALL", df[1L], "residuals are 0: no residual degrees of freedom!")
        cat("\n")
    }
    if (length(x$aliased) == 0L) {
        cat("\nNo Coefficients\n")
    }
    else {
        if (nsingular <- df[3L] - df[1L]) 
            cat("\nCoefficients: (", nsingular, " not defined because of singularities)\n", 
                sep = "")
        else cat("\nCoefficients:\n")
        coefs <- x$coefficients
        if (any(aliased <- x$aliased)) {
            cn <- names(aliased)
            coefs <- matrix(NA, length(aliased), 4, dimnames = list(cn, 
                colnames(coefs)))
            coefs[!aliased, ] <- x$coefficients
        }
        printCoefmat(coefs, digits = digits, signif.stars = signif.stars, 
            na.print = "NA", ...)
    }
    cat("\nResidual standard error:", format(signif(x$sigma, 
        digits)), "on", rdf, "degrees of freedom")
    cat("\n")
    if (nzchar(mess <- naprint(x$na.action))) 
        cat("  (", mess, ")\n", sep = "")
    if (!is.null(x$fstatistic)) {
        cat("Multiple R-squared: ", formatC(x$r.squared, digits = digits))
        cat(",\tAdjusted R-squared: ", formatC(x$adj.r.squared, 
            digits = digits), "\nF-statistic:", formatC(x$fstatistic[1L], 
            digits = digits), "on", x$fstatistic[2L], "and", 
            x$fstatistic[3L], "DF,  p-value:", format.pval(pf(x$fstatistic[1L], 
                x$fstatistic[2L], x$fstatistic[3L], lower.tail = FALSE), 
                digits = digits))
        cat("\n")
    }
    correl <- x$correlation
    if (!is.null(correl)) {
        p <- NCOL(correl)
        if (p > 1L) {
            cat("\nCorrelation of Coefficients:\n")
            if (is.logical(symbolic.cor) && symbolic.cor) {
                print(symnum(correl, abbr.colnames = NULL))
            }
            else {
                correl <- format(round(correl, 2), nsmall = 2, 
                  digits = digits)
                correl[!lower.tri(correl)] <- ""
                print(correl[-1, -p, drop = FALSE], quote = FALSE)
            }
        }
    }
    cat("\n")
    invisible(x)
}
<bytecode: 0x55e4dce10870>
<environment: namespace:stats>

17.2.4 Other resources