[[1]]
[1] "A"
[[2]]
[1] TRUE FALSE
[[3]]
[1] 0.5 1.0 1.5 2.0
[[4]]
[[4]][[1]]
[1] TRUE
[[4]][[2]]
[1] 1
[[5]]
function(x) x^2
Lecture 04
Lists are the other vector data structure in R, they differ from atomic vectors in that they can contain a heterogeneous collection of R object (e.g. atomic vectors, functions, other lists, etc.).
Often we want a more compact representation of a complex object, the str()
function is useful for this, particularly for lists.
Lists can contain other lists, meaning they don’t have to be flat
By default a vector will be coerced to a list (as a list is more general) if needed
Because of their more complex structure we often want to name the elements of a list (we can also do this with atomic vectors).
This can make accessing list elements more straight forward (and avoids the use of magic numbers)
List of 2
$ A: num 1
$ B:List of 2
..$ C: num 2
..$ D: num 3
Represent the following JSON data as a list in R.
05:00
NULL
sNULL
is a special value within R that represents nothing - it always has length zero and a type and mode of "NULL"
and cannot have any attributes.
0-length length coercion is a special case of length coercion when one of the arguments has length 0. In this special case the longer vector will have its length coerced to 0.
NULL
s and comparisonGiven the previous issue, comparisons and conditionals with NULL
s can be problematic.
Attributes are metadata that can be attached to objects in R. Some are special ( e.g. class
, comment
, dim
, dimnames
, names
, …) as they change the behavior of the object(s).
Attributes are implemented as a named list that is attached to an object. They can be interacted with via the attr
and attributes
functions.
The most commonly used / important attributes will usually have helper functions for getting and setting the attribute,
Factor objects are how R represents categorical data (e.g. a variable where there is a discrete set of possible outcomes).
[1] Sunny Cloudy Rainy Cloudy Cloudy
Levels: Cloudy Rainy Sunny
A factor is just an integer vector with two attributes: class
and levels
.
[1] Sunny Cloudy Rainy Cloudy Cloudy
Levels: Cloudy Rainy Sunny
List of 2
$ levels: chr [1:3] "Cloudy" "Rainy" "Sunny"
$ class : chr "factor"
The approach we just used is a bit clunky - generally the preferred method for construction an object with attributes from scratch is to use the structure
function.
Knowing factors are stored as integers help explain some of their more interesting behaviors:
class
The class
attribute is an additional layer to R’s type hierarchy,
value | typeof() |
mode() |
class() |
---|---|---|---|
TRUE |
logical | logical | logical |
1 |
double | numeric | numeric |
1L |
integer | numeric | integer |
"A" |
character | character | character |
NULL |
NULL | NULL | NULL |
list(1, "A") |
list | list | list |
factor("A") |
integer | numeric | factor |
function(x) x^2 |
closure | function | function |
+ |
builtin | function | function |
[ |
special | function | function |
function (x, digits = NULL, quote = TRUE, na.print = NULL, print.gap = NULL,
right = FALSE, max = NULL, width = NULL, useSource = TRUE,
...)
{
args <- pairlist(digits = digits, quote = quote, na.print = na.print,
print.gap = print.gap, right = right, max = max, width = width,
useSource = useSource, ...)
missings <- c(missing(digits), missing(quote), missing(na.print),
missing(print.gap), missing(right), missing(max), missing(width),
missing(useSource))
.Internal(print.default(x, args, missings))
}
<bytecode: 0x144d0c650>
<environment: namespace:base>
S3 is R’s first and simplest OO system. It is the only OO system used in the base and stats packages, and it’s the most commonly used system in CRAN packages. S3 is informal and ad hoc, but it has a certain elegance in its minimalism: you can’t take away any part of it and still have a useful OO system.
— Hadley Wickham, Advanced R
S3 objects and their related functions work using a very simple dispatch mechanism - a generic function is created whose sole job is to call the UseMethod
function which then calls a class specialized function using the naming convention: <generic>.<class>
We can see all of the specialized versions of the generic using the methods
function.
[1] plot.acf* plot.colors* plot.data.frame*
[4] plot.decomposed.ts* plot.default plot.dendrogram*
[7] plot.density* plot.ecdf plot.factor*
[10] plot.formula* plot.function plot.hclust*
[13] plot.histogram* plot.HoltWinters* plot.isoreg*
[16] plot.lm* plot.medpolish* plot.mlm*
[19] plot.ppr* plot.prcomp* plot.princomp*
[22] plot.profile.nls* plot.raster* plot.spec*
[25] plot.stepfun plot.stl* plot.table*
[28] plot.ts plot.tskernel* plot.TukeyHSD*
see '?methods' for accessing help and source code
[1] print.acf*
[2] print.activeConcordance*
[3] print.AES*
[4] print.anova*
[5] print.aov*
[6] print.aovlist*
[7] print.ar*
[8] print.Arima*
[9] print.arima0*
[10] print.AsIs
[11] print.aspell*
[12] print.aspell_inspect_context*
[13] print.bibentry*
[14] print.Bibtex*
[15] print.browseVignettes*
[16] print.by
[17] print.changedFiles*
[18] print.check_bogus_return*
[19] print.check_code_usage_in_package*
[20] print.check_compiled_code*
[21] print.check_demo_index*
[22] print.check_depdef*
[23] print.check_details*
[24] print.check_details_changes*
[25] print.check_doi_db*
[26] print.check_dotInternal*
[27] print.check_make_vars*
[28] print.check_nonAPI_calls*
[29] print.check_package_code_assign_to_globalenv*
[30] print.check_package_code_attach*
[31] print.check_package_code_data_into_globalenv*
[32] print.check_package_code_startup_functions*
[33] print.check_package_code_syntax*
[34] print.check_package_code_unload_functions*
[35] print.check_package_compact_datasets*
[36] print.check_package_CRAN_incoming*
[37] print.check_package_datalist*
[38] print.check_package_datasets*
[39] print.check_package_depends*
[40] print.check_package_description*
[41] print.check_package_description_encoding*
[42] print.check_package_license*
[43] print.check_packages_in_dir*
[44] print.check_packages_used*
[45] print.check_po_files*
[46] print.check_pragmas*
[47] print.check_Rd_line_widths*
[48] print.check_Rd_metadata*
[49] print.check_Rd_xrefs*
[50] print.check_RegSym_calls*
[51] print.check_S3_methods_needing_delayed_registration*
[52] print.check_so_symbols*
[53] print.check_T_and_F*
[54] print.check_url_db*
[55] print.check_vignette_index*
[56] print.checkDocFiles*
[57] print.checkDocStyle*
[58] print.checkFF*
[59] print.checkRd*
[60] print.checkRdContents*
[61] print.checkReplaceFuns*
[62] print.checkS3methods*
[63] print.checkTnF*
[64] print.checkVignettes*
[65] print.citation*
[66] print.cli_ansi_html_style*
[67] print.cli_ansi_string*
[68] print.cli_ansi_style*
[69] print.cli_boxx*
[70] print.cli_diff_chr*
[71] print.cli_doc*
[72] print.cli_progress_demo*
[73] print.cli_rule*
[74] print.cli_sitrep*
[75] print.cli_spark*
[76] print.cli_spinner*
[77] print.cli_tree*
[78] print.codoc*
[79] print.codocClasses*
[80] print.codocData*
[81] print.colorConverter*
[82] print.colors*
[83] print.compactPDF*
[84] print.condition
[85] print.connection
[86] print.CRAN_package_reverse_dependencies_and_views*
[87] print.data.frame
[88] print.Date
[89] print.default
[90] print.dendrogram*
[91] print.density*
[92] print.difftime
[93] print.dist*
[94] print.Dlist
[95] print.DLLInfo
[96] print.DLLInfoList
[97] print.DLLRegisteredRoutines
[98] print.document_context*
[99] print.document_position*
[100] print.document_range*
[101] print.document_selection*
[102] print.dummy_coef*
[103] print.dummy_coef_list*
[104] print.ecdf*
[105] print.eigen
[106] print.factanal*
[107] print.factor
[108] print.family*
[109] print.fileSnapshot*
[110] print.findLineNumResult*
[111] print.formula*
[112] print.ftable*
[113] print.function
[114] print.getAnywhere*
[115] print.glm*
[116] print.hashtab*
[117] print.hclust*
[118] print.help_files_with_topic*
[119] print.hexmode
[120] print.HoltWinters*
[121] print.hsearch*
[122] print.hsearch_db*
[123] print.htest*
[124] print.html*
[125] print.html_dependency*
[126] print.htmltools.selector*
[127] print.htmltools.selector.list*
[128] print.infl*
[129] print.integrate*
[130] print.isoreg*
[131] print.json*
[132] print.key_missing*
[133] print.kmeans*
[134] print.knitr_kable*
[135] print.Latex*
[136] print.LaTeX*
[137] print.libraryIQR
[138] print.listof
[139] print.lm*
[140] print.loadings*
[141] print.loess*
[142] print.logLik*
[143] print.ls_str*
[144] print.medpolish*
[145] print.MethodsFunction*
[146] print.mtable*
[147] print.NativeRoutineList
[148] print.news_db*
[149] print.nls*
[150] print.noquote
[151] print.numeric_version
[152] print.object_size*
[153] print.octmode
[154] print.packageDescription*
[155] print.packageInfo
[156] print.packageIQR*
[157] print.packageStatus*
[158] print.pairwise.htest*
[159] print.person*
[160] print.POSIXct
[161] print.POSIXlt
[162] print.power.htest*
[163] print.ppr*
[164] print.prcomp*
[165] print.princomp*
[166] print.proc_time
[167] print.quosure*
[168] print.quosures*
[169] print.raster*
[170] print.Rconcordance*
[171] print.Rd*
[172] print.recordedplot*
[173] print.restart
[174] print.RGBcolorConverter*
[175] print.RGlyphFont*
[176] print.rlang_box_done*
[177] print.rlang_box_splice*
[178] print.rlang_data_pronoun*
[179] print.rlang_dict*
[180] print.rlang_dyn_array*
[181] print.rlang_envs*
[182] print.rlang_error*
[183] print.rlang_fake_data_pronoun*
[184] print.rlang_lambda_function*
[185] print.rlang_message*
[186] print.rlang_trace*
[187] print.rlang_warning*
[188] print.rlang_zap*
[189] print.rlang:::list_of_conditions*
[190] print.rle
[191] print.rlib_bytes*
[192] print.rlib_error_3_0*
[193] print.rlib_trace_3_0*
[194] print.roman*
[195] print.scalar*
[196] print.sessionInfo*
[197] print.shiny.tag*
[198] print.shiny.tag.env*
[199] print.shiny.tag.list*
[200] print.shiny.tag.query*
[201] print.simple.list
[202] print.smooth.spline*
[203] print.socket*
[204] print.srcfile
[205] print.srcref
[206] print.stepfun*
[207] print.stl*
[208] print.StructTS*
[209] print.subdir_tests*
[210] print.summarize_CRAN_check_status*
[211] print.summary.aov*
[212] print.summary.aovlist*
[213] print.summary.ecdf*
[214] print.summary.glm*
[215] print.summary.lm*
[216] print.summary.loess*
[217] print.summary.manova*
[218] print.summary.nls*
[219] print.summary.packageStatus*
[220] print.summary.ppr*
[221] print.summary.prcomp*
[222] print.summary.princomp*
[223] print.summary.table
[224] print.summary.warnings
[225] print.summaryDefault
[226] print.table
[227] print.tables_aov*
[228] print.terms*
[229] print.ts*
[230] print.tskernel*
[231] print.TukeyHSD*
[232] print.tukeyline*
[233] print.tukeysmooth*
[234] print.undoc*
[235] print.vignette*
[236] print.warnings
[237] print.xfun_raw_string*
[238] print.xfun_rename_seq*
[239] print.xfun_strict_list*
[240] print.xgettext*
[241] print.xngettext*
[242] print.xtabs*
see '?methods' for accessing help and source code
function (x, quote = FALSE, max.levels = NULL, width = getOption("width"),
...)
{
ord <- is.ordered(x)
if (length(x) == 0L)
cat(if (ord)
"ordered"
else "factor", "()\n", sep = "")
else {
xx <- character(length(x))
xx[] <- as.character(x)
keepAttrs <- setdiff(names(attributes(x)), c("levels",
"class"))
attributes(xx)[keepAttrs] <- attributes(x)[keepAttrs]
print(xx, quote = quote, ...)
}
maxl <- if (is.null(max.levels))
TRUE
else max.levels
if (maxl) {
n <- length(lev <- encodeString(levels(x), quote = ifelse(quote,
"\"", "")))
colsep <- if (ord)
" < "
else " "
T0 <- "Levels: "
if (is.logical(maxl))
maxl <- {
width <- width - (nchar(T0, "w") + 3L + 1L +
3L)
lenl <- cumsum(nchar(lev, "w") + nchar(colsep,
"w"))
if (n <= 1L || lenl[n] <= width)
n
else max(1L, which.max(lenl > width) - 1L)
}
drop <- n > maxl
cat(if (drop)
paste(format(n), ""), T0, paste(if (drop)
c(lev[1L:max(1, maxl - 1)], "...", if (maxl > 1) lev[n])
else lev, collapse = colsep), "\n", sep = "")
}
if (!isTRUE(val <- .valid.factor(x)))
warning(val)
invisible(x)
}
<bytecode: 0x142f79320>
<environment: namespace:base>
If instead we have a class and want to know what specialized functions exist for that class, then we can again use the methods
function with the class
argument.
[1] [ [[ [[<- [<- all.equal
[6] as.character as.data.frame as.Date as.list as.logical
[11] as.POSIXlt as.vector c coerce droplevels
[16] format initialize is.na<- length<- levels<-
[21] Math Ops plot print relevel
[26] relist rep show slotsFromS3 summary
[31] Summary xtfrm
see '?methods' for accessing help and source code
Below we have defined an S3 method called report
, it is designed to return a message about the type/mode/class of an object passed to it.
Try running the report
function with different input types, what happens?
Now run rm("report.integer")
in your Console and try using the report
function again, what has changed?
What does this tell us about S3, types, modes, and classes?
What if we also rm("report.double")
?
From UseMethod
s R documentation:
If the object does not have a class attribute, it has an implicit class. Matrices and arrays have class “matrix” or “array” followed by the class of the underlying vector. Most vectors have class the result of
mode(x)
, except that integer vectors have classc("integer", "numeric")
and real vectors have classc("double", "numeric")
.
From Advanced R:
How does UseMethod() work? It basically creates a vector of method names, paste0(“generic”, “.”, c(class(x), “default”)), and then looks for each potential method in turn.
Why?
See @WhyDoesR
Sta 523 - Fall 2023