class: center, middle # Basic usage of R - 3 ## Introductory Computer Programming ### Deepayan Sarkar
--- layout: true # Functions --- * Most useful things in R happen by calling functions * Functions have one or more arguments * All arguments have names (available as variables inside the function) -- * Arguments may be compulsory or optional * Optional arguments usually have "default" values -- * Arguments may or may not be named when the function is called * Unnamed arguments are matched by position * Optional arguments are usually named * Functions normally also have a useful "return" value --- * For example, linear models are fit using the function `lm()` ```r str(lm) ``` ``` function (formula, data, subset, weights, na.action, method = "qr", model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, contrasts = NULL, offset, ...) ``` * These calls are equivalent ```r fm1 <- lm(mpg ~ wt, mtcars, (am == 0)) fm2 <- lm(mpg ~ wt, data = mtcars, method = "qr", subset = (am == 0)) coef(fm1) ``` ``` (Intercept) wt 31.416055 -3.785908 ``` ```r coef(fm2) ``` ``` (Intercept) wt 31.416055 -3.785908 ``` --- * Rule: named arguments are matched by name, remaining by position * Convention: - Named arguments are usually not followed by unnamed arguments - First few "standard" arguments are usually unnamed (matched by position) * The following call is equivalent to previous two, but not recommended ```r fm3 <- lm(mpg ~ wt, data = mtcars, (am == 0)) coef(fm3) ``` ``` (Intercept) wt 31.416055 -3.785908 ``` --- * The return value of `lm()` is a list .scrollable400[ ```r str(fm2) ``` ``` List of 12 $ coefficients : Named num [1:2] 31.42 -3.79 ..- attr(*, "names")= chr [1:2] "(Intercept)" "wt" $ residuals : Named num [1:19] 2.156 0.307 -0.217 -3.6 5.061 ... ..- attr(*, "names")= chr [1:19] "Hornet 4 Drive" "Hornet Sportabout" "Valiant" "Duster 360" ... $ effects : Named num [1:19] -74.744 -12.487 -0.614 -4 4.672 ... ..- attr(*, "names")= chr [1:19] "(Intercept)" "wt" "" "" ... $ rank : int 2 $ fitted.values: Named num [1:19] 19.2 18.4 18.3 17.9 19.3 ... ..- attr(*, "names")= chr [1:19] "Hornet 4 Drive" "Hornet Sportabout" "Valiant" "Duster 360" ... $ assign : int [1:2] 0 1 $ qr :List of 5 ..$ qr : num [1:19, 1:2] -4.359 0.229 0.229 0.229 0.229 ... .. ..- attr(*, "dimnames")=List of 2 .. .. ..$ : chr [1:19] "Hornet 4 Drive" "Hornet Sportabout" "Valiant" "Duster 360" ... .. .. ..$ : chr [1:2] "(Intercept)" "wt" .. ..- attr(*, "assign")= int [1:2] 0 1 ..$ qraux: num [1:2] 1.23 1.07 ..$ pivot: int [1:2] 1 2 ..$ tol : num 1e-07 ..$ rank : int 2 ..- attr(*, "class")= chr "qr" $ df.residual : int 17 $ xlevels : Named list() $ call : language lm(formula = mpg ~ wt, data = mtcars, subset = (am == 0), method = "qr") $ terms :Classes 'terms', 'formula' language mpg ~ wt .. ..- attr(*, "variables")= language list(mpg, wt) .. ..- attr(*, "factors")= int [1:2, 1] 0 1 .. .. ..- attr(*, "dimnames")=List of 2 .. .. .. ..$ : chr [1:2] "mpg" "wt" .. .. .. ..$ : chr "wt" .. ..- attr(*, "term.labels")= chr "wt" .. ..- attr(*, "order")= int 1 .. ..- attr(*, "intercept")= int 1 .. ..- attr(*, "response")= int 1 .. ..- attr(*, ".Environment")=
.. ..- attr(*, "predvars")= language list(mpg, wt) .. ..- attr(*, "dataClasses")= Named chr [1:2] "numeric" "numeric" .. .. ..- attr(*, "names")= chr [1:2] "mpg" "wt" $ model :'data.frame': 19 obs. of 2 variables: ..$ mpg: num [1:19] 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 ... ..$ wt : num [1:19] 3.21 3.44 3.46 3.57 3.19 ... ..- attr(*, "terms")=Classes 'terms', 'formula' language mpg ~ wt .. .. ..- attr(*, "variables")= language list(mpg, wt) .. .. ..- attr(*, "factors")= int [1:2, 1] 0 1 .. .. .. ..- attr(*, "dimnames")=List of 2 .. .. .. .. ..$ : chr [1:2] "mpg" "wt" .. .. .. .. ..$ : chr "wt" .. .. ..- attr(*, "term.labels")= chr "wt" .. .. ..- attr(*, "order")= int 1 .. .. ..- attr(*, "intercept")= int 1 .. .. ..- attr(*, "response")= int 1 .. .. ..- attr(*, ".Environment")=
.. .. ..- attr(*, "predvars")= language list(mpg, wt) .. .. ..- attr(*, "dataClasses")= Named chr [1:2] "numeric" "numeric" .. .. .. ..- attr(*, "names")= chr [1:2] "mpg" "wt" - attr(*, "class")= chr "lm" ``` ] --- * Individual elements can be extracted using list indexing ```r fm2$coefficients ``` ``` (Intercept) wt 31.416055 -3.785908 ``` ```r fm2$residuals ``` ``` Hornet 4 Drive Hornet Sportabout Valiant Duster 360 Merc 240D 2.155637322 0.307466517 -0.216815332 -3.600365503 5.060989634 Merc 230 Merc 280 Merc 280C Merc 450SE Merc 450SL 3.309553333 0.807466517 -0.592533483 0.392588263 0.005379702 Merc 450SLC Cadillac Fleetwood Lincoln Continental Chrysler Imperial Toyota Corona -1.905324922 -1.140040848 -0.481292938 3.519620367 -0.583793327 Dodge Challenger AMC Javelin Camaro Z28 Pontiac Firebird -2.589660880 -3.211463020 -3.578170470 2.340759068 ``` --- layout: true # Attributes --- * The names (derived from row names of the data) can be used as index ```r fm2$residuals["Chrysler Imperial"] ``` ``` Chrysler Imperial 3.51962 ``` * The names associated with a vector can be obtained using `names()` ```r names(fm2$residuals) ``` ``` [1] "Hornet 4 Drive" "Hornet Sportabout" "Valiant" "Duster 360" [5] "Merc 240D" "Merc 230" "Merc 280" "Merc 280C" [9] "Merc 450SE" "Merc 450SL" "Merc 450SLC" "Cadillac Fleetwood" [13] "Lincoln Continental" "Chrysler Imperial" "Toyota Corona" "Dodge Challenger" [17] "AMC Javelin" "Camaro Z28" "Pontiac Firebird" ``` --- * These names are actually stored as an _attribute_ called "names" ```r attr(fm2$residuals, "names") ``` ``` [1] "Hornet 4 Drive" "Hornet Sportabout" "Valiant" "Duster 360" [5] "Merc 240D" "Merc 230" "Merc 280" "Merc 280C" [9] "Merc 450SE" "Merc 450SL" "Merc 450SLC" "Cadillac Fleetwood" [13] "Lincoln Continental" "Chrysler Imperial" "Toyota Corona" "Dodge Challenger" [17] "AMC Javelin" "Camaro Z28" "Pontiac Firebird" ``` * Attributes are arbitrary R objects that can be attached to any other object * Typically used for programming convenience, normally not seen by users * However, some attributes are "special" --- * The "names" attribute can be extracted using the function `names()` * `dimnames()` similarly gives row / column names for matrices and arrays ```r dimnames(VADeaths) ``` ``` [[1]] [1] "50-54" "55-59" "60-64" "65-69" "70-74" [[2]] [1] "Rural Male" "Rural Female" "Urban Male" "Urban Female" ``` ```r attr(VADeaths, "dimnames") ``` ``` [[1]] [1] "50-54" "55-59" "60-64" "65-69" "70-74" [[2]] [1] "Rural Male" "Rural Female" "Urban Male" "Urban Female" ``` --- * For example, column names can be obtained as ```r dimnames(VADeaths)[[2]] ``` ``` [1] "Rural Male" "Rural Female" "Urban Male" "Urban Female" ``` * There are convenient shortcuts called `rownames()` and `colnames()` ```r colnames(VADeaths) ``` ``` [1] "Rural Male" "Rural Female" "Urban Male" "Urban Female" ``` --- * In fact, we can easily verify that this is what `colnames()` is doing by printing it ```r colnames ``` ``` function (x, do.NULL = TRUE, prefix = "col") { if (is.data.frame(x) && do.NULL) return(names(x)) dn <- dimnames(x) if (!is.null(dn[[2L]])) dn[[2L]] else { nc <- NCOL(x) if (do.NULL) NULL else if (nc > 0L) paste0(prefix, seq_len(nc)) else character() } }
``` * All R functions can be easily inspected in this way --- * Another very important attribute is "class" * For example, the return value of `lm()` has class "lm" ```r attr(fm2, "class") ``` ``` [1] "lm" ``` * The class of an object can also be obtained using the function `class()` ```r class(fm2) ``` ``` [1] "lm" ``` --- * The class of an object can (usually) be "removed" by setting it to `NULL` * This is not something you should actually do! ```r class(fm2) <- NULL ``` * Such objects will no longer have a "class" attribute ```r attr(fm2, "class") ``` ``` NULL ``` * However, it will still have a class (implicitly) ```r class(fm2) ``` ``` [1] "list" ``` -- * We will discuss the class attribute in more details next day --- layout: false class: center middle # Questions?