class: center, middle, inverse, title-slide # More Subsetting + S3 Objects ### Colin Rundel ### 2018-09-10 --- exclude: true --- class: middle count: false # Subsetting Matrices, Data Frames, and Arrays --- ## Subsetting Matrices ```r (x = matrix(1:6, nrow=2, ncol=3)) ``` ``` ## [,1] [,2] [,3] ## [1,] 1 3 5 ## [2,] 2 4 6 ``` .pull-left[ ```r x[1,3] ``` ``` ## [1] 5 ``` ```r x[1:2, 1:2] ``` ``` ## [,1] [,2] ## [1,] 1 3 ## [2,] 2 4 ``` ] .pull-right[ ```r x[, 1:2] ``` ``` ## [,1] [,2] ## [1,] 1 3 ## [2,] 2 4 ``` ```r x[-1,-3] ``` ``` ## [1] 2 4 ``` ] --- ## Preserving Subsetting Most of the time, R's `[` subset operator is a *preserving* operator, in that the returned object will have the same type as the parent. Confusingly, when used with a matrix or array `[` becomes a *simplifying* operator (does not preserve type) - this behavior is controlled by the `drop` argument. .pull-left[ ```r x[1, ] ``` ``` ## [1] 1 3 5 ``` ```r x[1, , drop=TRUE] ``` ``` ## [1] 1 3 5 ``` ```r x[1, , drop=FALSE] ``` ``` ## [,1] [,2] [,3] ## [1,] 1 3 5 ``` ] .pull-right[ ```r str(x[1, ]) ``` ``` ## int [1:3] 1 3 5 ``` ```r str(x[1, , drop=TRUE]) ``` ``` ## int [1:3] 1 3 5 ``` ```r str(x[1, , drop=FALSE]) ``` ``` ## int [1, 1:3] 1 3 5 ``` ] --- ## Preserving vs Simplifying Subsets Type | Simplifying | Preserving :----------------|:-------------------------|:----------------------------------------------------- Atomic Vector | `x[[1]]` | `x[1]` List | `x[[1]]` | `x[1]` Matrix / Array | `x[1, ]` <br/> `x[, 1]` | `x[1, , drop=FALSE]` <br/> `x[, 1, drop=FALSE]` Factor | `x[1:4, drop=TRUE]` | `x[1:4]` Data frame | `x[, 1]` <br/> `x[[1]]` | `x[, 1, drop=FALSE]` <br/> `x[1]` --- ## Factor Subsetting ```r (x = factor(c("BS", "MS", "PhD", "MS"))) ``` ``` ## [1] BS MS PhD MS ## Levels: BS MS PhD ``` ```r x[1:2] ``` ``` ## [1] BS MS ## Levels: BS MS PhD ``` ```r x[1:2, drop=TRUE] ``` ``` ## [1] BS MS ## Levels: BS MS ``` --- ## Data Frame Subsetting If provided with a single value, data frames assume you want to subset a column or columns - multiple values then the data frame is treated as a matrix. ```r df = data.frame(a = 1:2, b = 3:4) df[1] ``` ``` ## a ## 1 1 ## 2 2 ``` ```r df[[1]] ``` ``` ## [1] 1 2 ``` ```r df[, "a"] ``` ``` ## [1] 1 2 ``` --- ## ```r df["a"] ``` ``` ## a ## 1 1 ## 2 2 ``` ```r df[, "a", drop = FALSE] ``` ``` ## a ## 1 1 ## 2 2 ``` ```r df[1,] ``` ``` ## a b ## 1 1 3 ``` ```r df[c("a","b","a")] ``` ``` ## a b a.1 ## 1 1 3 1 ## 2 2 4 2 ``` --- class: middle count: false # Subsetting and assignment --- ## Subsetting and assignment Subsets can also be used with assignment to update specific values within an object. ```r x = c(1, 4, 7) ``` ```r x[2] = 2 x ``` ``` ## [1] 1 2 7 ``` ```r x[x %% 2 != 0] = x[x %% 2 != 0] + 1 x ``` ``` ## [1] 2 2 8 ``` ```r x[c(1,1)] = c(2,3) x ``` ``` ## [1] 3 2 8 ``` --- .pull-left[ ```r x = 1:6 x[c(2,NA)] = 1 x ``` ``` ## [1] 1 1 3 4 5 6 ``` ```r x = 1:6 x[c(TRUE,NA)] = 1 x ``` ``` ## [1] 1 2 1 4 1 6 ``` ] .pull-right[ ```r x = 1:6 x[c(-1,-3)] = 3 x ``` ``` ## [1] 1 3 3 3 3 3 ``` ```r x = 1:6 x[] = 6:1 x ``` ``` ## [1] 6 5 4 3 2 1 ``` ] --- ## Deleting list (df) elements ```r df = data.frame(a = 1:2, b = TRUE, c = c("A", "B")) ``` ```r df[["b"]] = NULL str(df) ``` ``` ## 'data.frame': 2 obs. of 2 variables: ## $ a: int 1 2 ## $ c: Factor w/ 2 levels "A","B": 1 2 ``` ```r df[,"c"] = NULL str(df) ``` ``` ## 'data.frame': 2 obs. of 1 variable: ## $ a: int 1 2 ``` --- ## Subsets of Subsets ```r df = data.frame(a = c(5,1,NA,3)) ``` ```r df$a[df$a == 5] = 0 df ``` ``` ## a ## 1 0 ## 2 1 ## 3 NA ## 4 3 ``` ```r df[1][df[1] == 3] = 0 df ``` ``` ## a ## 1 0 ## 2 1 ## 3 NA ## 4 0 ``` --- class: middle count: false # S3 Objects --- ## What is S3? <br/> > 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 .footnote[ * S3 should not be confused with R's other object oriented systems: S4, Reference classes, and R6*. ] --- ## An example .pull-left[ ```r print( c("A","B","A","C") ) ``` ``` ## [1] "A" "B" "A" "C" ``` ```r print( factor(c("A","B","A","C")) ) ``` ``` ## [1] A B A C ## Levels: A B C ``` ] .pull-right[ ```r print( data.frame(a=1:3, b=4:6) ) ``` ``` ## a b ## 1 1 4 ## 2 2 5 ## 3 3 6 ``` ] -- <br/> ```r print ``` ``` ## function (x, ...) ## UseMethod("print") ## <bytecode: 0x7fc5be9d8fb8> ## <environment: namespace:base> ``` --- ## Other examples .pull-left[ ```r mean ``` ``` ## function (x, ...) ## UseMethod("mean") ## <bytecode: 0x7fc5bf97cdf0> ## <environment: namespace:base> ``` ```r t.test ``` ``` ## function (x, ...) ## UseMethod("t.test") ## <bytecode: 0x7fc5bd1453c8> ## <environment: namespace:stats> ``` ] .pull-right[ ```r summary ``` ``` ## function (object, ...) ## UseMethod("summary") ## <bytecode: 0x7fc5c195d968> ## <environment: namespace:base> ``` ```r plot ``` ``` ## function (x, y, ...) ## UseMethod("plot") ## <bytecode: 0x7fc5bc32d968> ## <environment: namespace:graphics> ``` ] ```r sum ``` ``` ## function (..., na.rm = FALSE) .Primitive("sum") ``` --- ## What's going on? 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 named using the convention: `generic.class`. We can see all of the specialized versions of the generic using the `methods` function. ```r methods("plot") ``` ``` ## [1] plot.acf* plot.data.frame* plot.decomposed.ts* ## [4] plot.default plot.dendrogram* plot.density* ## [7] plot.ecdf plot.factor* plot.formula* ## [10] plot.function plot.hclust* plot.histogram* ## [13] plot.HoltWinters* plot.isoreg* plot.lm* ## [16] plot.medpolish* plot.mlm* plot.ppr* ## [19] plot.prcomp* plot.princomp* plot.profile.nls* ## [22] plot.R6* 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 ``` --- .small[ ```r methods("print") ``` ``` ## [1] print.acf* ## [2] print.AES* ## [3] print.anova* ## [4] print.aov* ## [5] print.aovlist* ## [6] print.ar* ## [7] print.Arima* ## [8] print.arima0* ## [9] print.AsIs ## [10] print.aspell* ## [11] print.aspell_inspect_context* ## [12] print.bibentry* ## [13] print.Bibtex* ## [14] print.boxx* ## [15] print.browseVignettes* ## [16] print.by ## [17] print.bytes* ## [18] print.changedFiles* ## [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_datasets* ## [38] print.check_package_depends* ## [39] print.check_package_description* ## [40] print.check_package_description_encoding* ## [41] print.check_package_license* ## [42] print.check_packages_in_dir* ## [43] print.check_packages_used* ## [44] print.check_po_files* ## [45] print.check_pragmas* ## [46] print.check_Rd_contents* ## [47] print.check_Rd_line_widths* ## [48] print.check_Rd_metadata* ## [49] print.check_Rd_xrefs* ## [50] print.check_RegSym_calls* ## [51] print.check_so_symbols* ## [52] print.check_T_and_F* ## [53] print.check_url_db* ## [54] print.check_vignette_index* ## [55] print.checkDocFiles* ## [56] print.checkDocStyle* ## [57] print.checkFF* ## [58] print.checkRd* ## [59] print.checkReplaceFuns* ## [60] print.checkS3methods* ## [61] print.checkTnF* ## [62] print.checkVignettes* ## [63] print.citation* ## [64] print.codoc* ## [65] print.codocClasses* ## [66] print.codocData* ## [67] print.colonnade* ## [68] print.colorConverter* ## [69] print.compactPDF* ## [70] print.condition ## [71] print.connection ## [72] print.CRAN_package_reverse_dependencies_and_views* ## [73] print.crayon* ## [74] print.data.frame ## [75] print.Date ## [76] print.default ## [77] print.dendrogram* ## [78] print.density* ## [79] print.difftime ## [80] print.dist* ## [81] print.Dlist ## [82] print.DLLInfo ## [83] print.DLLInfoList ## [84] print.DLLRegisteredRoutines ## [85] print.document_context* ## [86] print.document_position* ## [87] print.document_range* ## [88] print.document_selection* ## [89] print.dummy_coef* ## [90] print.dummy_coef_list* ## [91] print.ecdf* ## [92] print.eigen ## [93] print.factanal* ## [94] print.factor ## [95] print.family* ## [96] print.fileSnapshot* ## [97] print.findLineNumResult* ## [98] print.formula* ## [99] print.frame* ## [100] print.fseq* ## [101] print.ftable* ## [102] print.function ## [103] print.getAnywhere* ## [104] print.glm* ## [105] print.hclust* ## [106] print.help_files_with_topic* ## [107] print.hexmode ## [108] print.HoltWinters* ## [109] print.hsearch* ## [110] print.hsearch_db* ## [111] print.htest* ## [112] print.html* ## [113] print.html_dependency* ## [114] print.infl* ## [115] print.integrate* ## [116] print.isoreg* ## [117] print.kmeans* ## [118] print.knitr_kable* ## [119] print.Latex* ## [120] print.LaTeX* ## [121] print.libraryIQR ## [122] print.listof ## [123] print.lm* ## [124] print.loadings* ## [125] print.loess* ## [126] print.logLik* ## [127] print.ls_str* ## [128] print.medpolish* ## [129] print.MethodsFunction* ## [130] print.mtable* ## [131] print.NativeRoutineList ## [132] print.news_db* ## [133] print.nls* ## [134] print.noquote ## [135] print.numeric_version ## [136] print.object_size* ## [137] print.octmode ## [138] print.packageDescription* ## [139] print.packageInfo ## [140] print.packageIQR* ## [141] print.packageStatus* ## [142] print.pairwise.htest* ## [143] print.PDF_Array* ## [144] print.PDF_Dictionary* ## [145] print.pdf_doc* ## [146] print.pdf_fonts* ## [147] print.PDF_Indirect_Reference* ## [148] print.pdf_info* ## [149] print.PDF_Keyword* ## [150] print.PDF_Name* ## [151] print.PDF_Stream* ## [152] print.PDF_String* ## [153] print.person* ## [154] print.pillar* ## [155] print.pillar_ornament* ## [156] print.pillar_shaft* ## [157] print.pillar_vertical* ## [158] print.POSIXct ## [159] print.POSIXlt ## [160] print.power.htest* ## [161] print.ppr* ## [162] print.prcomp* ## [163] print.princomp* ## [164] print.proc_time ## [165] print.promise* ## [166] print.quosure* ## [167] print.quosures* ## [168] print.R6* ## [169] print.R6ClassGenerator* ## [170] print.raster* ## [171] print.Rcpp_stack_trace* ## [172] print.Rd* ## [173] print.recordedplot* ## [174] print.restart ## [175] print.RGBcolorConverter* ## [176] print.rif_shaft* ## [177] print.rlang_data_pronoun* ## [178] print.rle ## [179] print.roman* ## [180] print.root_criterion* ## [181] print.rule* ## [182] print.sessionInfo* ## [183] print.shiny.tag* ## [184] print.shiny.tag.list* ## [185] print.simple.list ## [186] print.smooth.spline* ## [187] print.socket* ## [188] print.spark* ## [189] print.squeezed_colonnade* ## [190] print.srcfile ## [191] print.srcref ## [192] print.stepfun* ## [193] print.stl* ## [194] print.StructTS* ## [195] print.subdir_tests* ## [196] print.summarize_CRAN_check_status* ## [197] print.summary.aov* ## [198] print.summary.aovlist* ## [199] print.summary.ecdf* ## [200] print.summary.glm* ## [201] print.summary.lm* ## [202] print.summary.loess* ## [203] print.summary.manova* ## [204] print.summary.nls* ## [205] print.summary.packageStatus* ## [206] print.summary.ppr* ## [207] print.summary.prcomp* ## [208] print.summary.princomp* ## [209] print.summary.table ## [210] print.summary.warnings ## [211] print.summaryDefault ## [212] print.table ## [213] print.tables_aov* ## [214] print.tbl* ## [215] print.tbl_df* ## [216] print.terms* ## [217] print.tree* ## [218] print.trunc_mat* ## [219] print.ts* ## [220] print.tskernel* ## [221] print.TukeyHSD* ## [222] print.tukeyline* ## [223] print.tukeysmooth* ## [224] print.undoc* ## [225] print.vignette* ## [226] print.warnings ## [227] print.x ## [228] print.xfun_raw_string* ## [229] print.xfun_strict_list* ## [230] print.xgettext* ## [231] print.xngettext* ## [232] print.xtabs* ## [233] print.y ## see '?methods' for accessing help and source code ``` ] --- ```r print.data.frame ``` ``` ## function (x, ..., digits = NULL, quote = FALSE, right = TRUE, ## row.names = TRUE) ## { ## n <- length(row.names(x)) ## if (length(x) == 0L) { ## cat(sprintf(ngettext(n, "data frame with 0 columns and %d row", ## "data frame with 0 columns and %d rows"), n), "\n", ## sep = "") ## } ## else if (n == 0L) { ## print.default(names(x), quote = FALSE) ## cat(gettext("<0 rows> (or 0-length row.names)\n")) ## } ## else { ## m <- as.matrix(format.data.frame(x, digits = digits, ## na.encode = FALSE)) ## if (!isTRUE(row.names)) ## dimnames(m)[[1L]] <- if (isFALSE(row.names)) ## rep.int("", n) ## else row.names ## print(m, ..., quote = quote, right = right) ## } ## invisible(x) ## } ## <bytecode: 0x7fc5be04d8e8> ## <environment: namespace:base> ``` --- ```r print.matrix ``` ``` ## Error in eval(expr, envir, enclos): object 'print.matrix' not found ``` -- ```r print.default ``` ``` ## function (x, digits = NULL, quote = TRUE, na.print = NULL, print.gap = NULL, ## right = FALSE, max = NULL, useSource = TRUE, ...) ## { ## noOpt <- missing(digits) && missing(quote) && missing(na.print) && ## missing(print.gap) && missing(right) && missing(max) && ## missing(useSource) && missing(...) ## .Internal(print.default(x, digits, quote, na.print, print.gap, ## right, max, useSource, noOpt)) ## } ## <bytecode: 0x7fc5be782708> ## <environment: namespace:base> ``` --- ## The other way 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 - this time with the `class` argument. ```r methods(class="data.frame") ``` ``` ## [1] [ [[ [[<- [<- $ ## [6] $<- aggregate anyDuplicated as_data_frame as_tibble ## [11] as.data.frame as.list as.matrix by cbind ## [16] coerce dim dimnames dimnames<- droplevels ## [21] duplicated edit format formula glimpse ## [26] head initialize is_vector_s3 is.na Math ## [31] merge na.exclude na.omit Ops plot ## [36] print prompt rbind row.names row.names<- ## [41] rowsum show shuffle slotsFromS3 split ## [46] split<- stack str subset summary ## [51] Summary t tail transform type_sum ## [56] type.convert unique unstack within ## see '?methods' for accessing help and source code ``` --- class: small ```r `[.data.frame` ``` ``` ## function (x, i, j, drop = if (missing(i)) TRUE else length(cols) == ## 1) ## { ## mdrop <- missing(drop) ## Narg <- nargs() - !mdrop ## has.j <- !missing(j) ## if (!all(names(sys.call()) %in% c("", "drop")) && !isS4(x)) ## warning("named arguments other than 'drop' are discouraged") ## if (Narg < 3L) { ## if (!mdrop) ## warning("'drop' argument will be ignored") ## if (missing(i)) ## return(x) ## if (is.matrix(i)) ## return(as.matrix(x)[i]) ## nm <- names(x) ## if (is.null(nm)) ## nm <- character() ## if (!is.character(i) && anyNA(nm)) { ## names(nm) <- names(x) <- seq_along(x) ## y <- NextMethod("[") ## cols <- names(y) ## if (anyNA(cols)) ## stop("undefined columns selected") ## cols <- names(y) <- nm[cols] ## } ## else { ## y <- NextMethod("[") ## cols <- names(y) ## if (!is.null(cols) && anyNA(cols)) ## stop("undefined columns selected") ## } ## if (anyDuplicated(cols)) ## names(y) <- make.unique(cols) ## attr(y, "row.names") <- .row_names_info(x, 0L) ## attr(y, "class") <- oldClass(x) ## return(y) ## } ## if (missing(i)) { ## if (drop && !has.j && length(x) == 1L) ## return(.subset2(x, 1L)) ## nm <- names(x) ## if (is.null(nm)) ## nm <- character() ## if (has.j && !is.character(j) && anyNA(nm)) { ## names(nm) <- names(x) <- seq_along(x) ## y <- .subset(x, j) ## cols <- names(y) ## if (anyNA(cols)) ## stop("undefined columns selected") ## cols <- names(y) <- nm[cols] ## } ## else { ## y <- if (has.j) ## .subset(x, j) ## else x ## cols <- names(y) ## if (anyNA(cols)) ## stop("undefined columns selected") ## } ## if (drop && length(y) == 1L) ## return(.subset2(y, 1L)) ## if (anyDuplicated(cols)) ## names(y) <- make.unique(cols) ## nrow <- .row_names_info(x, 2L) ## if (drop && !mdrop && nrow == 1L) ## return(structure(y, class = NULL, row.names = NULL)) ## else { ## attr(y, "class") <- oldClass(x) ## attr(y, "row.names") <- .row_names_info(x, 0L) ## return(y) ## } ## } ## xx <- x ## cols <- names(xx) ## x <- vector("list", length(x)) ## x <- .Internal(copyDFattr(xx, x)) ## oldClass(x) <- attr(x, "row.names") <- NULL ## if (has.j) { ## nm <- names(x) ## if (is.null(nm)) ## nm <- character() ## if (!is.character(j) && anyNA(nm)) ## names(nm) <- names(x) <- seq_along(x) ## x <- x[j] ## cols <- names(x) ## if (drop && length(x) == 1L) { ## if (is.character(i)) { ## rows <- attr(xx, "row.names") ## i <- pmatch(i, rows, duplicates.ok = TRUE) ## } ## xj <- .subset2(.subset(xx, j), 1L) ## return(if (length(dim(xj)) != 2L) xj[i] else xj[i, ## , drop = FALSE]) ## } ## if (anyNA(cols)) ## stop("undefined columns selected") ## if (!is.null(names(nm))) ## cols <- names(x) <- nm[cols] ## nxx <- structure(seq_along(xx), names = names(xx)) ## sxx <- match(nxx[j], seq_along(xx)) ## } ## else sxx <- seq_along(x) ## rows <- NULL ## if (is.character(i)) { ## rows <- attr(xx, "row.names") ## i <- pmatch(i, rows, duplicates.ok = TRUE) ## } ## for (j in seq_along(x)) { ## xj <- xx[[sxx[j]]] ## x[[j]] <- if (length(dim(xj)) != 2L) ## xj[i] ## else xj[i, , drop = FALSE] ## } ## if (drop) { ## n <- length(x) ## if (n == 1L) ## return(x[[1L]]) ## if (n > 1L) { ## xj <- x[[1L]] ## nrow <- if (length(dim(xj)) == 2L) ## dim(xj)[1L] ## else length(xj) ## drop <- !mdrop && nrow == 1L ## } ## else drop <- FALSE ## } ## if (!drop) { ## if (is.null(rows)) ## rows <- attr(xx, "row.names") ## rows <- rows[i] ## if ((ina <- anyNA(rows)) | (dup <- anyDuplicated(rows))) { ## if (!dup && is.character(rows)) ## dup <- "NA" %in% rows ## if (ina) ## rows[is.na(rows)] <- "NA" ## if (dup) ## rows <- make.unique(as.character(rows)) ## } ## if (has.j && anyDuplicated(nm <- names(x))) ## names(x) <- make.unique(nm) ## if (is.null(rows)) ## rows <- attr(xx, "row.names")[i] ## attr(x, "row.names") <- rows ## oldClass(x) <- oldClass(xx) ## } ## x ## } ## <bytecode: 0x7fc5bf9ade68> ## <environment: namespace:base> ``` --- ## Adding methods .pull-left[ ```r x = structure(c(1,2,3), class="x") x ``` ``` ## [1] "Class x!" ``` ] .pull-right[ ```r y = structure(c(1,2,3), class="y") y ``` ``` ## [1] "Class y!" ``` ] -- <div> .pull-left[ ```r print.x = function(x) print("Class x!") x ``` ``` ## [1] "Class x!" ``` ] .pull-right[ ```r print.y = function(y) print("Class y!") y ``` ``` ## [1] "Class y!" ``` ] </div> -- <div> .pull-left[ ```r class(x) = "y" x ``` ``` ## [1] "Class y!" ``` ] .pull-right[ ```r class(y) = "x" y ``` ``` ## [1] "Class x!" ``` ] </div> --- ## Defining a new S3 Generic ```r shuffle = function(x, ...) { UseMethod("shuffle") } shuffle.default = function(x) { n = length(x) x[sample(seq_len(n),n)] } shuffle.data.frame = function(df) { n = length(df) df[,sample(seq_len(n),n)] } ``` -- .pull-left[ ```r shuffle( 1:10 ) ``` ``` ## [1] 8 5 9 1 3 2 6 10 7 4 ``` ```r shuffle( letters[1:5] ) ``` ``` ## [1] "a" "e" "c" "d" "b" ``` ] .pull-right[ ```r shuffle( data.frame(a=1:2, b=3:4, c=5:6) ) ``` ``` ## c b a ## 1 5 3 1 ## 2 6 4 2 ``` ] --- class: middle count: false # Tibbles --- ## Modern data frames Hadley Wickham has a package that modifies data frames to be more modern, or as he calls them surly and lazy. ```r library(tibble) class(iris) ``` ``` ## [1] "data.frame" ``` ```r tbl_iris = as_tibble(iris) class(tbl_iris) ``` ``` ## [1] "tbl_df" "tbl" "data.frame" ``` --- ## Fancy Printing ```r tbl_iris ``` ``` ## # A tibble: 150 x 5 ## Sepal.Length Sepal.Width Petal.Length Petal.Width Species ## <dbl> <dbl> <dbl> <dbl> <fct> ## 1 5.1 3.5 1.4 0.2 setosa ## 2 4.9 3 1.4 0.2 setosa ## 3 4.7 3.2 1.3 0.2 setosa ## 4 4.6 3.1 1.5 0.2 setosa ## 5 5 3.6 1.4 0.2 setosa ## 6 5.4 3.9 1.7 0.4 setosa ## 7 4.6 3.4 1.4 0.3 setosa ## 8 5 3.4 1.5 0.2 setosa ## 9 4.4 2.9 1.4 0.2 setosa ## 10 4.9 3.1 1.5 0.1 setosa ## # ... with 140 more rows ``` --- ## Fancier printing ```r data_frame(x = rnorm(10,sd=5), y = rnorm(10)) ``` ``` ## # A tibble: 10 x 2 ## x y ## <dbl> <dbl> ## 1 6.63 0.533 ## 2 8.75 -1.08 ## 3 3.22 0.795 ## 4 -1.05 0.364 ## 5 15.5 -1.09 ## 6 12.1 0.883 ## 7 6.10 -0.562 ## 8 -7.50 -0.465 ## 9 4.26 -0.0503 ## 10 5.34 -0.0291 ``` --- ## Tibbles are lazy ```r tbl_iris[1,] ``` ``` ## # A tibble: 1 x 5 ## Sepal.Length Sepal.Width Petal.Length Petal.Width Species ## <dbl> <dbl> <dbl> <dbl> <fct> ## 1 5.1 3.5 1.4 0.2 setosa ``` .pull-left[ ```r tbl_iris[,"Species"] ``` ``` ## # A tibble: 150 x 1 ## Species ## <fct> ## 1 setosa ## 2 setosa ## 3 setosa ## 4 setosa ## 5 setosa ## 6 setosa ## 7 setosa ## 8 setosa ## 9 setosa ## 10 setosa ## # ... with 140 more rows ``` ] -- .pull-right[ ```r data_frame( x = 1:3, y = c("A","B","C") ) ``` ``` ## # A tibble: 3 x 2 ## x y ## <int> <chr> ## 1 1 A ## 2 2 B ## 3 3 C ``` ] --- ## Reverting a tbl ```r d = data_frame( x = 1:3, y = c("A","B","C") ) d ``` ``` ## # A tibble: 3 x 2 ## x y ## <int> <chr> ## 1 1 A ## 2 2 B ## 3 3 C ``` .pull-left[ ```r data.frame(d) ``` ``` ## x y ## 1 1 A ## 2 2 B ## 3 3 C ``` ] .pull-right[ ```r class(d) = "data.frame" d ``` ``` ## x y ## 1 1 A ## 2 2 B ## 3 3 C ``` ] --- ## Multiple classes ```r d = data_frame( x = 1:3, y = c("A","B","C") ) class(d) ``` ``` ## [1] "tbl_df" "tbl" "data.frame" ``` -- <br/> ```r class(d) = rev(class(d)) class(d) ``` ``` ## [1] "data.frame" "tbl" "tbl_df" ``` ```r d ``` ``` ## x y ## 1 1 A ## 2 2 B ## 3 3 C ``` --- class: middle count: false # HW2 & Github Pull Requests --- ## Acknowledgments Above materials are derived in part from the following sources: * Hadley Wickham - [Advanced R](http://adv-r.had.co.nz/) * [R Language Definition](http://stat.ethz.ch/R-manual/R-devel/doc/manual/R-lang.html)