class: left, middle, inverse background-image: url("https://live.staticflickr.com/65535/50362989122_a8ee154fea_k_d.jpg") background-size: cover # .orange[The Workflow of <br>Data Analysis] ### Environmental Data Literacy --- class: sectionTitle # .green[Actions] ## The *verbs* of data analysis --- background-image: url("https://live.staticflickr.com/65535/50362129663_0d640ad239_k_d.jpg") background-size: cover # Data Operators .pull-left[ There are a finite number of actions (verbs) that we can use on the raw data we work with. They can be combined to yield meaninful (or quimsical) inferences from our data: .redinline[ Is there more sun on Fridays than on the weekend?] .orangeinline[ What is the distribution of high-tide depths for each <br> day in January?] .blueinline[ Is there a visible relationship between water salinity &<br> measured pH?] ] --- background-image: url("https://live.staticflickr.com/65535/50362827791_a32934b310_k_d.jpg") background-size: cover # Select .pull-left[ Identify only subset of data columns that you are interested in using.] --- background-image: url("https://live.staticflickr.com/65535/50362989322_6aa00c8398_k_d.jpg") background-size: cover # Filter .pull-left[ Use only some subset of rows in the data based upon qualities wihtin the columns themselves. ] --- background-image: url("https://live.staticflickr.com/65535/50362827946_d8d5508dfd_k_d.jpg") background-size: cover # Mutate .pull-left[ Convert one data type to another, scaling, combining, or making any other derivative component. ] --- background-image: url("https://live.staticflickr.com/65535/50362129893_61851436c8_k_d.jpg") background-size: cover # Arrange .pull-left[ Reorder the data using values in one or more collumns to sort. ] --- background-image: url("https://live.staticflickr.com/65535/50362869456_c869b2a0a9_k_d.jpg") background-size: cover # Group .pull-left[ Partition the data set into groups based upon some taxonomy of categorization. ] --- background-image: url("https://live.staticflickr.com/65535/50362989492_d4e281b741_k_d.jpg") background-size: cover # Summarize .pull-left[ Perform operations on the data to characterize trends in the raw data as summary statistics. ] --- # Combinations Yield Inference Combining these actions together is how we perform the analyses.
--
--- # The Data The data we will be working with consist of data from the [Rice Rivers Center](https://ricerivers.vcu.edu) which contains water and atmospheric measurements from a stream of sensors in both the James River and on the bluff overlooking the river. ```r library( readr ) url <- "https://docs.google.com/spreadsheets/d/1Mk1YGH9LqjF7drJE-td1G_JkdADOU0eMlrP01WFBT8s/pub?gid=0&single=true&output=csv" rice <- read_csv( url ) names( rice ) ``` ``` ## [1] "DateTime" "RecordID" ## [3] "PAR" "WindSpeed_mph" ## [5] "WindDir" "AirTempF" ## [7] "RelHumidity" "BP_HG" ## [9] "Rain_in" "H2O_TempC" ## [11] "SpCond_mScm" "Salinity_ppt" ## [13] "PH" "PH_mv" ## [15] "Turbidity_ntu" "Chla_ugl" ## [17] "BGAPC_CML" "BGAPC_rfu" ## [19] "ODO_sat" "ODO_mgl" ## [21] "Depth_ft" "Depth_m" ## [23] "SurfaceWaterElev_m_levelNad83m" ``` --- class: sectionTitle # .green[Selecting] ## Grabbing *only* the variables you need --- # Column Selection Using the column numbers instead of names. ```r df <- rice[ c(1,3,5,13)] summary( df ) ``` ``` ## DateTime PAR WindDir PH ## Length:8199 Min. : 0.000 Min. : 0.00 Min. :6.43 ## Class :character 1st Qu.: 0.000 1st Qu.: 37.31 1st Qu.:7.50 ## Mode :character Median : 0.046 Median :137.30 Median :7.58 ## Mean : 241.984 Mean :146.20 Mean :7.60 ## 3rd Qu.: 337.900 3rd Qu.:249.95 3rd Qu.:7.69 ## Max. :1957.000 Max. :360.00 Max. :9.00 ## NA's :1 ``` --- # Readability & Code Maintenance .pull-left[ - Column names are probably better than column numbers - Additional assistance from RStudio via *pop-ups*. - Longer term readability (like next Tuesday & Beyond!) ] .pull-right[![Figure 1: Popup help for column names in `RStudio` for a data frame in memory](https://live.staticflickr.com/65535/50359964467_03232a3716_w_d.jpg)] --- class: sectionTitle # .green[Filtering] ## Extract only the records (rows) needed --- # Row Indices If you have some indication of which set of data you are interested in looking at, you can use the raw numerical values for the rows and extract subsets. .left-column[ Values for 1/1/2014 ```r df1 <- df[ 1:96, ] head( df1 ) ``` ] .right-column[ ``` ## # A tibble: 6 x 4 ## DateTime PAR WindDir PH ## <chr> <dbl> <dbl> <dbl> ## 1 1/1/2014 12:00:00 AM 0 14.6 7.22 ## 2 1/1/2014 12:15:00 AM 0 18.5 7.52 ## 3 1/1/2014 12:30:00 AM 0 16.2 7.53 ## 4 1/1/2014 12:45:00 AM 0 11.5 7.53 ## 5 1/1/2014 1:00:00 AM 0 11.3 7.55 ## 6 1/1/2014 1:15:00 AM 0 20.0 7.56 ``` ] -- .red[Requires us to have very intimate knowledge of how many records constitute a day and that **every** day is the same.] --- # Logical Indices We can use logical operators to create `TRUE/FALSE` values to select rows of interest. .pull-left[ Operator | Definition :-------:|------------------------ `!=` | Not equal to `==` | Equal to `>` | Strictly greater than `>=` | Greater than OR equal to `<` | Strictly less than `<=` | Less than or equal to. ] -- .pull-right[ ] --- # Logical Indices We can use logical operators to create `TRUE/FALSE` (and `NA`) values as a vector. ```r idx <- df$PAR > 0 idx[1:200] ``` ``` ## [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE ## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE ## [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE ## [37] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE ## [49] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE ## [61] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE ## [73] TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE ## [85] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE ## [97] FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE ## [109] FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE ## [121] TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE ## [133] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE ## [145] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE ## [157] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE ## [169] TRUE TRUE TRUE FALSE TRUE TRUE FALSE TRUE FALSE FALSE FALSE FALSE ## [181] TRUE TRUE FALSE FALSE TRUE TRUE FALSE FALSE TRUE TRUE TRUE FALSE ## [193] TRUE TRUE FALSE FALSE FALSE TRUE TRUE FALSE ``` --- # Logical Indices Then use them to serve as indices on the original data. Only the `TRUE` values will be returned. ```r df1 <- df[ idx, ] summary( df1 ) ``` ``` ## DateTime PAR WindDir PH ## Length:4967 Min. : 0.003 Min. : 0.00 Min. :6.48 ## Class :character 1st Qu.: 3.828 1st Qu.: 48.94 1st Qu.:7.51 ## Mode :character Median : 213.300 Median :182.80 Median :7.59 ## Mean : 399.442 Mean :164.10 Mean :7.61 ## 3rd Qu.: 679.250 3rd Qu.:258.90 3rd Qu.:7.71 ## Max. :1957.000 Max. :359.90 Max. :8.64 ## NA's :1 ``` --- # Function Indices We can also use various functions that return `TRUE/FALSE` values. ```r df[ is.na(df$PH), ] ``` ``` ## # A tibble: 1 x 4 ## DateTime PAR WindDir PH ## <chr> <dbl> <dbl> <dbl> ## 1 1/17/2014 1:00:00 PM 1077 152. NA ``` --- # Mathematical Operations The *modulo* operator returns the remainder after simple division (e.g., 10 modulo 3 = 1). It can be used to grab 'every x<sup>th</sup>' element. Here is an example of every other value (the even ones). ```r (1:20 %% 2 ) == 0 ``` ``` ## [1] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE ## [13] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE ``` -- Or every third ```r (1:20 %% 3 ) == 0 ``` ``` ## [1] FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE ## [13] FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE ``` --- # Random Samples There is often times that we will want to go grab a random subset of data (often when looking to see you have enough sample size). We can use the `sample()` function. -- Grab 10 random records from `df`. .pull-left[ ```r idx <- sample( 1:nrow(df), size=10, replace=FALSE ) idx ``` ``` ## [1] 4685 1402 3776 8161 203 7580 6935 7754 2915 3571 ``` ] -- .pull-right[ ```r df[idx,] ``` ``` ## # A tibble: 10 x 4 ## DateTime PAR WindDir PH ## <chr> <dbl> <dbl> <dbl> ## 1 2/18/2014 7:00:00 PM 8.17 297. 7.52 ## 2 1/15/2014 2:15:00 PM 698. 193. 7.44 ## 3 2/9/2014 7:45:00 AM 0.033 8.51 7.44 ## 4 3/27/2014 12:00:00 AM 0 37.4 7.91 ## 5 1/3/2014 2:30:00 AM 0.062 314 7.44 ## 6 3/20/2014 10:45:00 PM 0.007 348. 7.99 ## 7 3/14/2014 5:30:00 AM 0 18.1 7.82 ## 8 3/22/2014 6:15:00 PM 139. 277. 7.86 ## 9 1/31/2014 8:30:00 AM 34.3 6.57 7.58 ## 10 2/7/2014 4:30:00 AM 0 132. 7.46 ``` ] --- # Combinations of Indices Multiple criteria. "Wind from particular direction *and* not night." ```r par <- df$PAR > 0 wind <- df$WindDir < 30 cbind( par, wind )[30:35,] ``` ``` ## par wind ## [1,] FALSE TRUE ## [2,] FALSE TRUE ## [3,] FALSE TRUE ## [4,] TRUE TRUE ## [5,] TRUE FALSE ## [6,] TRUE FALSE ``` --- # Logical Operators AND & OR .pull-left[ `&`-operator must all be `TRUE` Condition | Result ----------------|---------- `FALSE & FALSE` | `FALSE` `FALSE & TRUE` | `FALSE` `TRUE & FALSE` | `FALSE` `TRUE & TRUE` | `TRUE` ```r cbind( par, wind, AND = par & wind )[30:35,] ``` ``` ## par wind AND ## [1,] FALSE TRUE FALSE ## [2,] FALSE TRUE FALSE ## [3,] FALSE TRUE FALSE ## [4,] TRUE TRUE TRUE ## [5,] TRUE FALSE FALSE ## [6,] TRUE FALSE FALSE ``` ] -- .pull-right[ `|`-operator must have at least one `TRUE` Condition | Result ----------------|---------- `FALSE & FALSE` | `FALSE` `FALSE & TRUE` | `TRUE` `TRUE & FALSE` | `TRUE` `TRUE & TRUE` | `TRUE` ```r cbind( par, wind, OR = par | wind)[30:35,] ``` ``` ## par wind OR ## [1,] FALSE TRUE TRUE ## [2,] FALSE TRUE TRUE ## [3,] FALSE TRUE TRUE ## [4,] TRUE TRUE TRUE ## [5,] TRUE FALSE TRUE ## [6,] TRUE FALSE TRUE ``` ] --- # Logical Operators XOR & NOT .pull-left[ `xor`-operator *only* one `TRUE` Condition | Result ----------------|---------- `FALSE & FALSE` | `FALSE` `FALSE & TRUE` | `TRUE` `TRUE & FALSE` | `TRUE` `TRUE & TRUE` | `FALSE` ```r cbind( par, wind, XOR = xor(par,wind) )[30:35,] ``` ``` ## par wind XOR ## [1,] FALSE TRUE TRUE ## [2,] FALSE TRUE TRUE ## [3,] FALSE TRUE TRUE ## [4,] TRUE TRUE FALSE ## [5,] TRUE FALSE TRUE ## [6,] TRUE FALSE TRUE ``` ] -- .pull-right[ `!`-flips the logical result Condition | Result ----------------|---------- `!FALSE` | `TRUE` `!TRUE` | `FALSE` ```r cbind( par, NOT_PAR = !par )[30:35,] ``` ``` ## par NOT_PAR ## [1,] FALSE TRUE ## [2,] FALSE TRUE ## [3,] FALSE TRUE ## [4,] TRUE FALSE ## [5,] TRUE FALSE ## [6,] TRUE FALSE ``` ] --- class: sectionTitle # 😱 .blue[Mutation] ## Creating derivative data components --- # Raw Data -> Usable Data Data is often derived from text. - `read_csv()` must make an estimate of a column data type should be. - Estimates are often *least divisive* data type (e.g., `character`). -- Consider the `DateTime` column in the `rice` data. ```r rice$DateTime[1] ``` ``` ## [1] "1/1/2014 12:00:00 AM" ``` -- ```r class( rice$DateTime ) ``` ``` ## [1] "character" ``` --- # Date & Time Challenges We must consider the following when attempting to conduct *operations* on date and time units. 1. Many different calendars. 2. Leap days, years, seconds. 3. Time Zones (looking at you Arizona). 4. Non-consistent base units (60 seconds, 60 minutes, 24 hours, 7 days, 28/29/30/31 days, 12 months, 100 years, 10 centuries) --- # The Unix Epoch - Time Zero! .red[.center[.large[00:00:00 January 1, 1970]]] Time on computers is kept as the number of seconds since the *epoch*. It is only .blueinline[displayed] in the Gregorian, Julian, Chinese, Jewish, and other calendars. ```r Sys.time() ``` ``` ## [1] "2020-09-28 13:47:01 EDT" ``` -- ```r unclass( Sys.time() ) ``` ``` ## [1] 1601315222 ``` --- # Making Time ⏱ To convert something like 1/1/2014 12:00:00 AM from `character` to a `time` object, we need to specify the layout of the elements within the string so the functions know what to operate on. .pull-left[ - Month as 1 or 2 digits - Day as 1 or 2 digits - Year as 4 digits - a space to separate date from time - hour (not 24-hour though) - minutes in 2 digits - seconds in 2 digits - a space to separate time from timezone - timezone - / separating date objects - : separating time objects ] -- .pull-right[ ```r rice$DateTime[1] ``` ``` ## [1] "1/1/2014 12:00:00 AM" ``` Look at the help file for `?strptime` to see these and other encodings. ```r library( lubridate ) format <- "%m/%d/%Y %I:%M:%S %p" x <- parse_date_time( rice$DateTime[1], orders=format, tz="EST") x ``` ``` ## [1] "2014-01-01 EST" ``` ] --- # Making Lots of Time ```r rice$DateTime <- parse_date_time( rice$DateTime, orders=format, tz="EST") summary( rice$DateTime ) ``` ``` ## Min. 1st Qu. Median ## "2014-01-01 00:00:00" "2014-01-22 08:22:30" "2014-02-12 16:45:00" ## Mean 3rd Qu. Max. ## "2014-02-12 16:45:00" "2014-03-06 01:07:30" "2014-03-27 09:30:00" ``` -- ```r rice$DateTime[8199] - rice$DateTime[1] ``` ``` ## Time difference of 85.39583 days ``` -- ```r txt <- paste( "Entry 5000 '", rice$DateTime[5000], "' is julian ordinal day ",yday( rice$DateTime[5000] ), sep="") txt ``` ``` ## [1] "Entry 5000 '2014-02-22 01:45:00' is julian ordinal day 53" ``` --- class: sectionTitle # .green[Grouping] ## Partitioning Data --- # Partitioning Data Into Groups ```r rice$Month <- month(rice$DateTime) summary( rice$Month ) ``` ``` ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 1.000 1.000 2.000 1.946 3.000 3.000 ``` --- # Partitioning Data Into Groups ```r rice$Month <- month( rice$DateTime, label=TRUE, abbr=FALSE ) summary( rice$Month ) ``` ``` ## January February March April May June July August ## 2976 2688 2535 0 0 0 0 0 ## September October November December ## 0 0 0 0 ``` ```r class( rice$Month ) ``` ``` ## [1] "ordered" "factor" ``` --- # Refactoring Factors ```r rice$Month <- droplevels( rice$Month ) summary( rice$Month ) ``` ``` ## January February March ## 2976 2688 2535 ``` --- # Partitioning Data Into Groups ```r airTemp <- by( rice$AirTempF, rice$Month, mean ) airTemp ``` ``` ## rice$Month: January ## [1] 34.69795 ## ------------------------------------------------------------ ## rice$Month: February ## [1] 39.74403 ## ------------------------------------------------------------ ## rice$Month: March ## [1] 42.59907 ``` --- class: sectionTitle # .blue[Summary] ## Pulling it all together <svg style="height:0.8em;top:.04em;position:relative;fill:steelblue;" viewBox="0 0 512 512"><path d="M200 288H88c-21.4 0-32.1 25.8-17 41l32.9 31-99.2 99.3c-6.2 6.2-6.2 16.4 0 22.6l25.4 25.4c6.2 6.2 16.4 6.2 22.6 0L152 408l31.1 33c15.1 15.1 40.9 4.4 40.9-17V312c0-13.3-10.7-24-24-24zm112-64h112c21.4 0 32.1-25.9 17-41l-33-31 99.3-99.3c6.2-6.2 6.2-16.4 0-22.6L481.9 4.7c-6.2-6.2-16.4-6.2-22.6 0L360 104l-31.1-33C313.8 55.9 288 66.6 288 88v112c0 13.3 10.7 24 24 24zm96 136l33-31.1c15.1-15.1 4.4-40.9-17-40.9H312c-13.3 0-24 10.7-24 24v112c0 21.4 25.9 32.1 41 17l31-32.9 99.3 99.3c6.2 6.2 16.4 6.2 22.6 0l25.4-25.4c6.2-6.2 6.2-16.4 0-22.6L408 360zM183 71.1L152 104 52.7 4.7c-6.2-6.2-16.4-6.2-22.6 0L4.7 30.1c-6.2 6.2-6.2 16.4 0 22.6L104 152l-33 31.1C55.9 198.2 66.6 224 88 224h112c13.3 0 24-10.7 24-24V88c0-21.3-25.9-32-41-16.9z"/></svg> --- # Summarizing Data All of these activities discussed lead towards some results such as: - Creating a tabular output of the results. - Plotting some graphical display of the results. - Serving as the input data for subsequent data analyses. Each of these methodologies requires us to exit the work flow, after putting together all these parts, and make another `data.frame`. --- # Graphical & Data Frame Output Since we already have a bit of practice working with making data frames and taking them to make graphical output, we will focus here on how to create tabular output. ```r airTemp <- by( (rice$AirTempF-32) * 5/9, rice$Month, mean ) humidity <- by( rice$RelHumidity, rice$Month, mean ) waterTemp <- by( rice$H2O_TempC, rice$Month, mean, na.rm=TRUE ) highTide <- by( rice$Depth_m, rice$Month, max ) df <- data.frame( Month = names( airTemp ) ) df$AirTemp <- as.numeric( airTemp ) df$Humidity <- as.numeric( humidity ) df$WaterTemp <- as.numeric( waterTemp ) df$HighTide <- as.numeric( highTide ) df ``` ``` ## Month AirTemp Humidity WaterTemp HighTide ## 1 January 1.498863 58.34487 3.676346 5.288280 ## 2 February 4.302240 60.38674 5.289107 5.388254 ## 3 March 5.888374 56.27460 7.959093 5.454091 ``` --- # Tabular Summaries Tabular output can be done by hand, but there is a much easier way to make tables using `knitr::kable`, allowing a lot of customizations. This approach makes tables for markdown, html, pdf, or docx outputs. ```r library( knitr ) t <- kable( df, format = "html", caption = "Table 1: Air and water parameters measured at the Rice Rivers Center" ) t ``` <table> <caption>Table 1: Air and water parameters measured at the Rice Rivers Center</caption> <thead> <tr> <th style="text-align:left;"> Month </th> <th style="text-align:right;"> AirTemp </th> <th style="text-align:right;"> Humidity </th> <th style="text-align:right;"> WaterTemp </th> <th style="text-align:right;"> HighTide </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> January </td> <td style="text-align:right;"> 1.498863 </td> <td style="text-align:right;"> 58.34487 </td> <td style="text-align:right;"> 3.676346 </td> <td style="text-align:right;"> 5.288280 </td> </tr> <tr> <td style="text-align:left;"> February </td> <td style="text-align:right;"> 4.302240 </td> <td style="text-align:right;"> 60.38674 </td> <td style="text-align:right;"> 5.289107 </td> <td style="text-align:right;"> 5.388254 </td> </tr> <tr> <td style="text-align:left;"> March </td> <td style="text-align:right;"> 5.888374 </td> <td style="text-align:right;"> 56.27460 </td> <td style="text-align:right;"> 7.959093 </td> <td style="text-align:right;"> 5.454091 </td> </tr> </tbody> </table> --- # Styling Tables We can apply various styling to a table using functions from the `kableExtra` package. ```r library( kableExtra ) ``` .pull-left[ ```r kable_classic( t, html_font = '\"Times New Roman\"') ``` <table class=" lightable-classic" style='font-family: "Times New Roman"; margin-left: auto; margin-right: auto;'> <caption>Table 1: Air and water parameters measured at the Rice Rivers Center</caption> <thead> <tr> <th style="text-align:left;"> Month </th> <th style="text-align:right;"> AirTemp </th> <th style="text-align:right;"> Humidity </th> <th style="text-align:right;"> WaterTemp </th> <th style="text-align:right;"> HighTide </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> January </td> <td style="text-align:right;"> 1.498863 </td> <td style="text-align:right;"> 58.34487 </td> <td style="text-align:right;"> 3.676346 </td> <td style="text-align:right;"> 5.288280 </td> </tr> <tr> <td style="text-align:left;"> February </td> <td style="text-align:right;"> 4.302240 </td> <td style="text-align:right;"> 60.38674 </td> <td style="text-align:right;"> 5.289107 </td> <td style="text-align:right;"> 5.388254 </td> </tr> <tr> <td style="text-align:left;"> March </td> <td style="text-align:right;"> 5.888374 </td> <td style="text-align:right;"> 56.27460 </td> <td style="text-align:right;"> 7.959093 </td> <td style="text-align:right;"> 5.454091 </td> </tr> </tbody> </table> ] -- .pull-right[ ```r kable_paper( t, "hover" ) ``` <table class=" lightable-paper lightable-hover" style='font-family: "Arial Narrow", arial, helvetica, sans-serif; margin-left: auto; margin-right: auto;'> <caption>Table 1: Air and water parameters measured at the Rice Rivers Center</caption> <thead> <tr> <th style="text-align:left;"> Month </th> <th style="text-align:right;"> AirTemp </th> <th style="text-align:right;"> Humidity </th> <th style="text-align:right;"> WaterTemp </th> <th style="text-align:right;"> HighTide </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> January </td> <td style="text-align:right;"> 1.498863 </td> <td style="text-align:right;"> 58.34487 </td> <td style="text-align:right;"> 3.676346 </td> <td style="text-align:right;"> 5.288280 </td> </tr> <tr> <td style="text-align:left;"> February </td> <td style="text-align:right;"> 4.302240 </td> <td style="text-align:right;"> 60.38674 </td> <td style="text-align:right;"> 5.289107 </td> <td style="text-align:right;"> 5.388254 </td> </tr> <tr> <td style="text-align:left;"> March </td> <td style="text-align:right;"> 5.888374 </td> <td style="text-align:right;"> 56.27460 </td> <td style="text-align:right;"> 7.959093 </td> <td style="text-align:right;"> 5.454091 </td> </tr> </tbody> </table> ] --- # Table Themes Customized headers. ```r tbl1 <- kable_classic( t ) add_header_above( tbl1, c(" " = 1, "Atmospheric" = 2, "Water" = 2) ) ``` <table class=" lightable-classic" style='font-family: "Arial Narrow", "Source Sans Pro", sans-serif; margin-left: auto; margin-right: auto;'> <caption>Table 1: Air and water parameters measured at the Rice Rivers Center</caption> <thead> <tr> <th style="empty-cells: hide;" colspan="1"></th> <th style="padding-bottom:0; padding-left:3px;padding-right:3px;text-align: center; " colspan="2"><div style="border-bottom: 1px solid #111111; margin-bottom: -1px; ">Atmospheric</div></th> <th style="padding-bottom:0; padding-left:3px;padding-right:3px;text-align: center; " colspan="2"><div style="border-bottom: 1px solid #111111; margin-bottom: -1px; ">Water</div></th> </tr> <tr> <th style="text-align:left;"> Month </th> <th style="text-align:right;"> AirTemp </th> <th style="text-align:right;"> Humidity </th> <th style="text-align:right;"> WaterTemp </th> <th style="text-align:right;"> HighTide </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> January </td> <td style="text-align:right;"> 1.498863 </td> <td style="text-align:right;"> 58.34487 </td> <td style="text-align:right;"> 3.676346 </td> <td style="text-align:right;"> 5.288280 </td> </tr> <tr> <td style="text-align:left;"> February </td> <td style="text-align:right;"> 4.302240 </td> <td style="text-align:right;"> 60.38674 </td> <td style="text-align:right;"> 5.289107 </td> <td style="text-align:right;"> 5.388254 </td> </tr> <tr> <td style="text-align:left;"> March </td> <td style="text-align:right;"> 5.888374 </td> <td style="text-align:right;"> 56.27460 </td> <td style="text-align:right;"> 7.959093 </td> <td style="text-align:right;"> 5.454091 </td> </tr> </tbody> </table> --- # Table Customization ```r kable_styling(t, bootstrap_options = c("striped", "hover", "condensed", "responsive")) ``` <table class="table table-striped table-hover table-condensed table-responsive" style="margin-left: auto; margin-right: auto;"> <caption>Table 1: Air and water parameters measured at the Rice Rivers Center</caption> <thead> <tr> <th style="text-align:left;"> Month </th> <th style="text-align:right;"> AirTemp </th> <th style="text-align:right;"> Humidity </th> <th style="text-align:right;"> WaterTemp </th> <th style="text-align:right;"> HighTide </th> </tr> </thead> <tbody> <tr> <td style="text-align:left;"> January </td> <td style="text-align:right;"> 1.498863 </td> <td style="text-align:right;"> 58.34487 </td> <td style="text-align:right;"> 3.676346 </td> <td style="text-align:right;"> 5.288280 </td> </tr> <tr> <td style="text-align:left;"> February </td> <td style="text-align:right;"> 4.302240 </td> <td style="text-align:right;"> 60.38674 </td> <td style="text-align:right;"> 5.289107 </td> <td style="text-align:right;"> 5.388254 </td> </tr> <tr> <td style="text-align:left;"> March </td> <td style="text-align:right;"> 5.888374 </td> <td style="text-align:right;"> 56.27460 </td> <td style="text-align:right;"> 7.959093 </td> <td style="text-align:right;"> 5.454091 </td> </tr> </tbody> </table> --- class: middle background-image: url("https://live.staticflickr.com/65535/50367566131_85c1285e2f_o_d.png") background-position: right background-size: auto .center[ # Questions? ![Peter Sellers](https://live.staticflickr.com/65535/50382906427_2845eb1861_o_d.gif+) ] <p> </p> .bottom[ If you have any questions for about the content presented herein, please feel free to [submit them to me](https://docs.google.com/forms/d/e/1FAIpQLScrAGM5Zl8vZTPqV8DVSnSrf_5enypyp0717jG4PZiTlVHDjQ/viewform?usp=sf_link) and I'll get back to you as soon as possible.]