{ "cells": [ { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "# Testing Spark + `sparklyr` - part 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Table of Contents\n", "\n", "- [Kickstart](#Kickstart)\n", "- [R console](#Launch-R-console-first)\n", "- [Jupyter](#Launch-Jupyter)\n", "- [Uploading the data in JSON format](#Uploading-the-data-in-JSON-format)\n", "- [Spark and R in Jupyter](#Spark-and-R-in-Jupyter)\n", "- [Reading JSON into Spark context: `reviews_Books_5.json`](#Reading-JSON-into-Spark-context:-reviews_Books_5.json)\n", " - [Prepare dataset](#Prepare-dataset)\n", " - [Dichotomize & Tokenize](#Dichotomize-&-Tokenize)\n", "- [Workaround: process `bin_reviews` in PySpark](#Workaround:-process-bin_reviews-in-PySpark)\n", "- [Returning to `sparklyr`](#Returning-to-sparklyr)\n", "- [Word counts](#Word-counts)\n", "- [Graphs](#Graphs)\n", "- [Model](#Model)\n", " - [Split Data](#Split-Data)\n", " - [Fit data](#Fit-data)\n", " - [Predict](#Predict)\n", "- [Session](#Session)\n", " - [Paths recognised by R](#Paths-recognised-by-R)\n", " - [R session info](#R-session-info)\n", "- [References](#References)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Kickstart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Please, read the [pyspark course](https://github.com/javicacheiro/pyspark_course/blob/master/unit_1_tools.ipynb) here (points 1.1 to 1.3)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Updated jul 2019]\n", "\n", "Open a terminal\n", "\n", "Connect to one of the login nodes of the Hadoop Hortonworks Data Platform (HDP) cluster (remember to activate Forticlient VPN first!):\n", "\n", " MY_CESGA_USER='abcdef' # my CESGA username \n", " ssh $MY_CESGA_USER@hadoop3.cesga.es\n", "\n", "In the new HDP server you have to load the Anaconda module that has the R distribution that works with Spark. \n", "\n", "This command needs to be executed everytime a new console is opened at CESGA:\n", "\n", " module load anaconda2 # run only once for every console \n", " \n", "To see the available modules type:\n", " \n", " module available # module av" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Launch R console first" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Configuring Spark and R kernel using .bashrc (currently not recommended)\n", "\n", "
\n", "\n", " \n", "*We could add environment variables to .bashrc to avoid setting `Sys.setenv` in `R`.*\n", "\n", "However, it is better to set `Sys.setenv()` as the **Anaconda version may change!** \n", "\n", "\n", " cd $HOME\n", " export R_PROFILE_USER=/usr/hdp/2.4.2.0-258/spark/R/lib/SparkR/profile/shell.R\n", " # reload .bashrc\n", " source .bashrc\n", " \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Open R\n", "\n", "Launch **R** (version 3.5.1 as of july 2019):\n", "\n", " R\n", "\n", "### Install libraries in R\n", "\n", "Install the libraries as needed. When you finish, exit the interactive `sparkR` session.\n", "\n", " > install.packages(c(\"sparklyr\", \"dplyr\", \"knitr\", \"repr\", \"tidytext\", \"tidyr\", \"purrr\", \"ggplot2\", \"viridis\", \"gridExtra\", \"rbokeh\"))\n", " > q()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "Sys.getenv('R_PROFILE_USER')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Launch Jupyter\n", "\n", "To init a Jupyter notebook:\n", "\n", "- Open a new console window.\n", "\n", "- Connect to one of the login nodes of the Hadoop Hortonworks Data Platform (HDP) cluster: \n", "\n", " ssh $MY_CESGA_USER@hadoop.cesga.es\n", "\n", "- Load Anaconda2 distribution:\n", "\n", " module load anaconda2\n", "\n", "- Launch the Jupyter notebook: \n", "\n", " start_jupyter\n", " \n", "\n", "- Follow the instructions in the console. You may be asked to paste an URL token into your browser. \n", "\n", "- Open the provided link in the browser\n", "\n", "The notebook you have launched is tightly integrated with Spark in order to:\n", "\n", "- Automatically opens a sparkR session with the cluster\n", "- Dynamically expands the required executors in the cluster\n", "- The console provides useful debugging information, showing Spark messages.\n", "\n", "When you finish your interactive work remember to close the notebook properly:\n", "\n", "- File -> Close and Halt\n", "\n", "\n", "**Tip**: it is a good idea to leave two consoles open simultaneously, one for Jupyter (to open the notebook) and the other for Bash and sparkR commands.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Uploading the data in JSON format " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, we need to upload our data from our NFS **HOME** to the HDFS **HOME** directory. \n", "- You can add a single file, or an entire folder.\n", "- You can also list or delete files, folders.\n", "\n", "### HDFS overview and commands\n", "\n", "See the [pyspark course](https://github.com/javicacheiro/pyspark_course/blob/master/unit_1_tools.ipynb) here (point 1.2) for HDFS basic commands.\n", "\n", "Let's define some variables:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " # my username \n", " MY_CESGA_USER='abcdef' \n", " \n", " # my HDFS HOME \n", " MY_HDFS_HOME=/user/$MY_CESGA_USER/ \n", " \n", " # my NFS HOME \n", " MY_NFS_HOME=$HOME" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "HDFS basic commands:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " # import data into hdfs (jscars.json): \n", " hdfs dfs -put $MY_NFS_HOME/Rsession/sparklyr_start/amazon/reviews_Books_5.json # adapt to your path\n", " \n", " # list files \n", " hdfs dfs -ls \n", " # list files in a directory \n", " hdfs dfs -ls $MY_HDFS_HOME\n", " # create a directory called 'data': \n", " hdfs dfs -mkdir data \n", " # delete a directory: \n", " hdfs dfs -rm -r -f data\n", " # delete files, folders from hdfs\n", " hdfs dfs -rm -r -f amazon/reviews_Books_5.json" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Spark and R in Jupyter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Configuring Spark and R " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Set `R` environment variables (needed for Jupyter notebooks in the cluster `R` installation)." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Sys.setenv(SPARK_HOME='/usr/hdp/2.4.2.0-258/spark/R/lib/SparkR/profile/shell.R') \n", " # commented after being added to .bashrc\n", ".libPaths(c(file.path(Sys.getenv('SPARK_HOME'), 'R', 'lib'), .libPaths()))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "Sys.getenv('SPARK_HOME')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Load libraries:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "options(warn = -1) # disable warnings" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": true }, "outputs": [], "source": [ "c(\"sparklyr\", \"dplyr\", \"knitr\", \"repr\", \"tidytext\", \"tidyr\", \"purrr\", \"ggplot2\", \"viridis\", \"gridExtra\", \"rbokeh\")\n", "lapply(x, require, character.only = TRUE, quietly = TRUE)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Loading spark context - RDDs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Currently there are three types of contexts:\n", "\n", "- Local context: \n", " - Interactive. \n", " - If the user exits session, the tasks are terminated (use `screen` to run after session close).\n", " - All processes reside in the LOGIN node (both drivers and executors).\n", " - Can only be used for tasks that require very few resources.\n", " - .Rmd notebook to run in your local computer\n", "- YARN-client: \n", " - Interactive.\n", " - If the user exits session, the tasks are terminated (use `screen` to run after session close).\n", " - The driver resides in the LOGIN node, but the executors are in the CLUSTER nodes. Thus, executors can use all the memory available for the task in the CLUSTER nodes.\n", " - Can be used for memory-intensive tasks.\n", "- YARN-cluster:\n", " - Not interactive.\n", " - Both the driver and the executors reside in the CLUSTER nodes.\n", " - Can be used for memory-intensive tasks.\n", " - Currenty doesn't seem available for this version of `R/sparklyr`.\n", " \n", "Defining a new context (`sc`) overwrites the previous one." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": true }, "outputs": [], "source": [ "SPARK_HOME = Sys.getenv('SPARK_HOME')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Initiating spark context: local (for 'low memory' tasks only!)\n", "# sc <- spark_connect(master = \"local\", spark_home = SPARK_HOME)\n", "\n", "# Initiating spark context: yarn (for loading bigger datasets)\n", "sc <- spark_connect(master = \"yarn-client\", spark_home = SPARK_HOME)\n", "# sc <- spark_connect(master = \"yarn-client\", spark_home = \"/usr/hdp/2.4.2.0-258/spark\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reading JSON into Spark context: `reviews_Books_5.json`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will use a [dataset of Amazon Product Data](http://snap.stanford.edu/data/amazon/productGraph/categoryFiles/reviews_Books_5.json.gz) [1] that contains 8.9M book reviews from Amazon, spanning May 1996 - July 2014.\n", "\n", "Dataset characteristics:\n", "\n", "- Number of reviews: 8.9M\n", "- Size: 8.8GB (uncompressed)\n", "- HDFS blocks: 70 (each with 3 replicas)\n", "\n", "[1] Image-based recommendations on styles and substitutes J. McAuley, C. Targett, J. Shi, A. van den Hengel SIGIR, 2015 http://jmcauley.ucsd.edu/data/amazon/. \n", "\n", "I am translating into R the following tutorial: Sentiment analysis with Spark ML. [Material for Machine Learning Workshop Galicia 2016](http://nbviewer.jupyter.org/github/javicacheiro/machine_learning_galicia_2016/blob/master/notebooks/sentiment_analysis-amazon_books.ipynb)." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true }, "outputs": [], "source": [ "books <- spark_read_json(sc, name = \"books\", path = \"amazon/reviews_Books_5.json\") \n", "# very big dataset" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here I used the Hive function `rpad` to truncate the variable `reviewText` to 30 characters. This allows for a correct display of the table. \n", "See more Hive functions in the [References](#References) section below. And also [this](http://www.folkstalk.com/2011/11/string-functions-in-hive.html):" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\t\n", "\t\n", "\t\n", "\n", "
asinhelpfuloverallreviewText_truncreviewTimereviewerIDreviewerNamesummaryunixReviewTime
000100039X 0, 0 5 Spiritually and mentally inspi 12 16, 2012 A10000012B7CGYKOMPQ4L Adam Wonderful! 1355616000
000100039X 0, 2 5 This is one my must have books 12 11, 2003 A2S166WSCFIFP5 adead_poet@hotmail.com \"adead_poet@hotmail.com\"close to god 1071100800
000100039X 0, 0 5 This book provides a reflectio 01 18, 2014 A1BM81XB4QHOA3 Ahoro Blethends \"Seriously\" Must Read for Life Afficianados 1390003200
\n" ], "text/latex": [ "\\begin{tabular}{r|lllllllll}\n", " asin & helpful & overall & reviewText\\_trunc & reviewTime & reviewerID & reviewerName & summary & unixReviewTime\\\\\n", "\\hline\n", "\t 000100039X & 0, 0 & 5 & Spiritually and mentally inspi & 12 16, 2012 & A10000012B7CGYKOMPQ4L & Adam & Wonderful! & 1355616000 \\\\\n", "\t 000100039X & 0, 2 & 5 & This is one my must have books & 12 11, 2003 & A2S166WSCFIFP5 & adead\\_poet@hotmail.com \"adead\\_poet@hotmail.com\" & close to god & 1071100800 \\\\\n", "\t 000100039X & 0, 0 & 5 & This book provides a reflectio & 01 18, 2014 & A1BM81XB4QHOA3 & Ahoro Blethends \"Seriously\" & Must Read for Life Afficianados & 1390003200 \\\\\n", "\\end{tabular}\n" ], "text/markdown": [ "\n", "asin | helpful | overall | reviewText_trunc | reviewTime | reviewerID | reviewerName | summary | unixReviewTime | \n", "|---|---|---|\n", "| 000100039X | 0, 0 | 5 | Spiritually and mentally inspi | 12 16, 2012 | A10000012B7CGYKOMPQ4L | Adam | Wonderful! | 1355616000 | \n", "| 000100039X | 0, 2 | 5 | This is one my must have books | 12 11, 2003 | A2S166WSCFIFP5 | adead_poet@hotmail.com \"adead_poet@hotmail.com\" | close to god | 1071100800 | \n", "| 000100039X | 0, 0 | 5 | This book provides a reflectio | 01 18, 2014 | A1BM81XB4QHOA3 | Ahoro Blethends \"Seriously\" | Must Read for Life Afficianados | 1390003200 | \n", "\n", "\n" ], "text/plain": [ " asin helpful overall reviewText_trunc reviewTime \n", "1 000100039X 0, 0 5 Spiritually and mentally inspi 12 16, 2012\n", "2 000100039X 0, 2 5 This is one my must have books 12 11, 2003\n", "3 000100039X 0, 0 5 This book provides a reflectio 01 18, 2014\n", " reviewerID reviewerName \n", "1 A10000012B7CGYKOMPQ4L Adam \n", "2 A2S166WSCFIFP5 adead_poet@hotmail.com \"adead_poet@hotmail.com\"\n", "3 A1BM81XB4QHOA3 Ahoro Blethends \"Seriously\" \n", " summary unixReviewTime\n", "1 Wonderful! 1355616000 \n", "2 close to god 1071100800 \n", "3 Must Read for Life Afficianados 1390003200 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "books %>%\n", " mutate(reviewText_trunc = as.character(rpad(reviewText, 30, '...'))) %>%\n", " select(asin, helpful, overall, reviewText_trunc, reviewTime, reviewerID, reviewerName, summary, unixReviewTime) %>%\n", " head(3) %>%\n", " collect()" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "$reviewText\n", "$reviewText$name\n", "[1] \"reviewText\"\n", "\n", "$reviewText$type\n", "[1] \"StringType\"\n", "\n", "\n", "$overall\n", "$overall$name\n", "[1] \"overall\"\n", "\n", "$overall$type\n", "[1] \"DoubleType\"\n", "\n", "\n" ] } ], "source": [ "# sdf_schema(books)\n", "books %>%\n", " mutate(reviewText_trunc = as.character(rpad(reviewText, 20, '...'))) %>%\n", " select(reviewText, overall) %>% \n", " sdf_schema() %>%\n", " print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Summary of the counts for each review score:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\n", "
overalln
5 4980815
4 2223094
3 955189
2 415110
1 323833
\n" ], "text/latex": [ "\\begin{tabular}{r|ll}\n", " overall & n\\\\\n", "\\hline\n", "\t 5 & 4980815\\\\\n", "\t 4 & 2223094\\\\\n", "\t 3 & 955189\\\\\n", "\t 2 & 415110\\\\\n", "\t 1 & 323833\\\\\n", "\\end{tabular}\n" ], "text/markdown": [ "\n", "overall | n | \n", "|---|---|---|---|---|\n", "| 5 | 4980815 | \n", "| 4 | 2223094 | \n", "| 3 | 955189 | \n", "| 2 | 415110 | \n", "| 1 | 323833 | \n", "\n", "\n" ], "text/plain": [ " overall n \n", "1 5 4980815\n", "2 4 2223094\n", "3 3 955189\n", "4 2 415110\n", "5 1 323833" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "books %>%\n", " count(overall, sort = TRUE) %>%\n", " collect() " ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### Prepare dataset" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "We will avoid neutral reviews by keeping only reviews with 1 or 5 stars overall score. We will also filter out the reviews that contain no text." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "reviews <- books %>%\n", " filter(overall == 1 | overall == 5) %>%\n", " filter(reviewText != '')" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\t\n", "\t\n", "\t\n", "\n", "
overallreviewText_trunc
5 Spiritually and mentally inspi
5 This is one my must have books
5 This book provides a reflectio
\n" ], "text/latex": [ "\\begin{tabular}{r|ll}\n", " overall & reviewText\\_trunc\\\\\n", "\\hline\n", "\t 5 & Spiritually and mentally inspi\\\\\n", "\t 5 & This is one my must have books\\\\\n", "\t 5 & This book provides a reflectio\\\\\n", "\\end{tabular}\n" ], "text/markdown": [ "\n", "overall | reviewText_trunc | \n", "|---|---|---|\n", "| 5 | Spiritually and mentally inspi | \n", "| 5 | This is one my must have books | \n", "| 5 | This book provides a reflectio | \n", "\n", "\n" ], "text/plain": [ " overall reviewText_trunc \n", "1 5 Spiritually and mentally inspi\n", "2 5 This is one my must have books\n", "3 5 This book provides a reflectio" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "reviews %>%\n", " mutate(reviewText_trunc = as.character(rpad(reviewText, 30, '...'))) %>%\n", " select(overall, reviewText_trunc) %>%\n", " head(3) %>%\n", " collect()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will use `cache` when the lineage of your RDD branches out or when an RDD is used multiple times like in a loop" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# tbl_cache(sc, reviews, force = TRUE)\n", "## tbl_uncache(sc, books)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Total row count:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\t\n", "\n", "
n
5304187
\n" ], "text/latex": [ "\\begin{tabular}{r|l}\n", " n\\\\\n", "\\hline\n", "\t 5304187\\\\\n", "\\end{tabular}\n" ], "text/markdown": [ "\n", "n | \n", "|---|\n", "| 5304187 | \n", "\n", "\n" ], "text/plain": [ " n \n", "1 5304187" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "reviews %>%\n", " count() %>%\n", " collect()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So far, so good." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Dichotomize & Tokenize" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will convert the numerical covariate `overall` to binary (0/1) features (\"binarize\"). \n", "Then we'll divide the reviews text into word-tokens (\"tokenize\")." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true }, "outputs": [], "source": [ "bin_reviews <- reviews %>% \n", " ft_binarizer(threshold = 2.5, input.col = 'overall', output.col = 'label') %>% \n", " select(reviewText, overall, label)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": true }, "outputs": [], "source": [ "tokenized_reviews <- bin_reviews %>% \n", " ft_tokenizer(input.col = 'reviewText', output.col = 'word')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Visualize the resulting table and structure:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\t\n", "\n", "
reviewText_truncoveralllabelword
Spiritually and ment 5 1 spiritually, and , mentally , inspiring! , a , book , that , allows , you , to , question , your , morals , and , will , help , you , discover , who , you , really , are!
\n" ], "text/latex": [ "\\begin{tabular}{r|llll}\n", " reviewText\\_trunc & overall & label & word\\\\\n", "\\hline\n", "\t Spiritually and ment & 5 & 1 & spiritually, and , mentally , inspiring! , a , book , that , allows , you , to , question , your , morals , and , will , help , you , discover , who , you , really , are! \\\\\n", "\\end{tabular}\n" ], "text/markdown": [ "\n", "reviewText_trunc | overall | label | word | \n", "|---|\n", "| Spiritually and ment | 5 | 1 | spiritually, and , mentally , inspiring! , a , book , that , allows , you , to , question , your , morals , and , will , help , you , discover , who , you , really , are! | \n", "\n", "\n" ], "text/plain": [ " reviewText_trunc overall label\n", "1 Spiritually and ment 5 1 \n", " word \n", "1 spiritually, and , mentally , inspiring! , a , book , that , allows , you , to , question , your , morals , and , will , help , you , discover , who , you , really , are! " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "tokenized_reviews %>% \n", " mutate(reviewText_trunc = as.character(rpad(reviewText, 20, '...'))) %>%\n", " select(reviewText_trunc, overall, label, word) %>% \n", " head(1) %>%\n", " collect()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "# Source: lazy query [?? x 4]\n", "# Database: spark_connection\n", " reviewText_trunc overall label word\n", " \n", "1 Spiritually and mentally inspi 5 1 \n", "2 This is one my must have books 5 1 \n", "3 This book provides a reflectio 5 1 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "tokenized_reviews %>%\n", " mutate(reviewText_trunc = as.character(rpad(reviewText, 30, '...'))) %>%\n", " select(reviewText_trunc, overall, label, word) %>% \n", " head(3) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we see that the variable `word` is a **list-column**. To process it we would have to use [`tidyr::unnest`](https://www.rdocumentation.org/packages/tidyr/versions/0.6.3/topics/unnest). \n", "However, working with R methods such as `unnest` implies that the dataset must be downloaded to memory, which is unfeasible given its size. \n", "Unfortunately, as of today there's no method for unnesting in `sparklyr` (see [here](https://campus.datacamp.com/courses/introduction-to-spark-in-r-using-sparklyr/going-native-use-the-native-interface-to-manipulate-spark-dataframes?ex=6)). However it is listed as a [feature request](https://github.com/rstudio/sparklyr/issues/536) in GitHub. \n", "As an example, you can see what `unnest` can do in R: " ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\t\n", "\t\n", "\t\n", "\t\n", "\t\n", "\n", "
word
spiritually
and
mentally
inspiring!
a
\n" ], "text/latex": [ "\\begin{tabular}{r|l}\n", " word\\\\\n", "\\hline\n", "\t spiritually\\\\\n", "\t and \\\\\n", "\t mentally \\\\\n", "\t inspiring! \\\\\n", "\t a \\\\\n", "\\end{tabular}\n" ], "text/markdown": [ "\n", "word | \n", "|---|---|---|---|---|\n", "| spiritually | \n", "| and | \n", "| mentally | \n", "| inspiring! | \n", "| a | \n", "\n", "\n" ], "text/plain": [ " word \n", "1 spiritually\n", "2 and \n", "3 mentally \n", "4 inspiring! \n", "5 a " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "tokenized_reviews %>%\n", " select(word) %>%\n", " head(10) %>%\n", " collect() %>%\n", " mutate(word = lapply(word, as.character)) %>%\n", " unnest(word) %>% \n", " head(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Workaround: process `bin_reviews` in PySpark" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When a method is not present in `sparklyr`, the easiest solution is resorting to [**PySpark**](https://spark.apache.org/docs/0.9.0/python-programming-guide.html), which exposes the Spark (Scala) programming model to Python. \n", "A great tutorial to start is this [PySpark Course](https://github.com/javicacheiro/pyspark_course), by @javicacheiro. \n", "We will start feeding some data to PySpark, so first we must save our dataset `bin_reviews` in HDFS:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": true }, "outputs": [], "source": [ "spark_write_json(bin_reviews, \"amazon/bin_reviews.json\", mode = NULL, options = list())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Just to be sure, we can check if the database has been saved:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " $ hdfs dfs -ls amazon" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Follow the PySpark transformations to the data, in the notebook [sparklyr_python.ipynb](./sparklyr_python.ipynb): \n", "- In PySpark, we will tokenize our `words` variable. \n", "- We will remove the stop words.\n", "- We will 'flatten' or 'explode' our `words` column to have each word in its own row.\n", "- Then, we'll reload the transformed dataset! (Thanks, pySpark!)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Returning to `sparklyr`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Import the transformed data into `sparklyr` again: " ] }, { "cell_type": "code", "execution_count": 101, "metadata": { "collapsed": true }, "outputs": [], "source": [ "options(repr.plot.width=12, repr.plot.height=5)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": true }, "outputs": [], "source": [ "unnested_reviews <- spark_read_json(sc, name = \"unnested_reviews_json\", path = \"amazon/unnested_reviews_json\") %>%\n", " filter(length(word) > 2) %>%\n", " mutate(word2 = regexp_replace(word, \"[^a-zA-Z0-9]+\", \"\")) %>% \n", " group_by(label) %>% \n", " count(word2, sort = TRUE) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note the **Hive/PostgreSQL** function [`regexp_replace`](https://www.postgresql.org/docs/9.4/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP) used to remove punctuation and special marks." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Word counts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Positive reviews:" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": true }, "outputs": [], "source": [ "positive_reviews <- unnested_reviews %>% \n", " filter(label==\"1\") %>%\n", " arrange(desc(n)) %>% \n", " head(10) %>% \n", " collect()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Negative reviews:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": true }, "outputs": [], "source": [ "negative_reviews <- unnested_reviews %>% \n", " filter(label==\"0\") %>%\n", " arrange(desc(n)) %>% \n", " head(10) %>% \n", " collect()" ] }, { "cell_type": "code", "execution_count": 193, "metadata": { "collapsed": true }, "outputs": [], "source": [ "total_reviews <- positive_reviews %>%\n", " bind_rows(negative_reviews) %>%\n", " arrange(desc(n))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Graphs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using **ggplot2**:" ] }, { "cell_type": "code", "execution_count": 196, "metadata": { "collapsed": true }, "outputs": [], "source": [ "total_reviews$label <- factor(total_reviews$label, labels = c(\"negative\", \"positive\"))\n", "\n", "g <- total_reviews %>% \n", " ggplot(aes(x=reorder(word2, -n))) +\n", " xlab(\"words in reviews\") + ylab(\"count\") + \n", " theme_bw()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Printing **ggplot2** plots:" ] }, { "cell_type": "code", "execution_count": 197, "metadata": { "collapsed": false }, "outputs": [ { "data": {}, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n3X///S+++GKYbgRBsG3btmw2m06nexc4+uijw3QjCIJEInHZZZdls9l//dd/7erqeuSRR776\n1a/GYrG2tra2traurq4pU6Ykk8lVq1YVYU/6hREcAAAAUIoaGxufe+653/72t3/4wx+effbZ\n3//+97lcbucFRo8evfPk4YcfHgTBSy+9tH79+iAIrrrqqquuuupt63zrrbf6uOqiEXAAAABA\nKbrmmmsuvfTSfffd9/TTT587d+6RRx559NFHv8fy8Xg8CILa2tpsNhsEwbe//e3x48e/bZkR\nI0b0XcHFJeAAAACAktPR0XH55Zefe+65P/3pT2OxWDjzbSM4nnvuuZ0nn3nmmSAIhg8fPnz4\n8CAIKisrjz322N53//znP69Zs+a///f/3teVF4t7cAAAAEDJefXVVzOZzKhRo3rTjdWrV7/+\n+us7Pwh25cqV/+f//J/wdXd39/e///3GxsYTTjhhwIABxxxzzC233PLiiy+G76bT6dbW1ksu\nuSSRSPTzjvQbIzgAAACg5Bx88MH77bffVVddtW3bthEjRjz11FP33nvvJz7xidWrV//yl78M\n7y16xBFHnHTSSVOmTGlubn7wwQf/9Kc/XX/99YMHDw6C4Prrrz/66KM///nPn3nmmfvss899\n9923du3ae++9N7yM5SNJwAEAAAAlp7q6evny5RdddNHChQubmpqOPvroNWvWrFy5cs6cOddd\nd10YcFxwwQXt7e233377iy++OGrUqKVLl06aNCn8eEtLy7PPPnvJJZc8/PDDHR0do0ePXr58\n+Ze//OWi7lPfEnAAAABAqfj1r3/d+/rTn/70Y489tvO7Z5111llnnRW+7r1W5bzzznvHVY0Y\nMeLBBx983618ZLgHBwAAABB5Ag4AAAAg8gQcAAAAQOTtasAxadKkP/3pT389/4knnpg5c+Ye\nLQkAAADgg3mfgGPLX/zsZz9bv379lv9q8+bNv/jFL/7pn/6pf2oFAAAAeEfv8xSV5ubm3ten\nn376Oy5z3HHH7cmKAAAAAD6g9wk4brjhhvDFnDlzvv71rx900EFvW6CqquqUU07pk9IAAAAA\nds37BBwXXnhh+OKhhx6aPn36YYcd1vclAQAAQJma+9zhe3aF145+ds+usGS9T8DR69e//nVf\nlgEAAADw4e1qwNHW1nbRRRf97//9v7u7u//63S1btuzRqgAAAAA+gF0NOL75zW8uXrz4s5/9\n7OjRoysqdvXhsgAAAAD9YFcDjkceeeTMM89cunRpLBbr04IAAAAAPqhdHYvR2dl5/PHHSzcA\nAACAErSrAcdRRx317LPlcudVAAAAIFp2NeC48cYbH3jggRtvvLGnp6dPCwIAAAD4oHY14Jg3\nb95+++13wQUXNDY2Dh8+/DP/VZ+WCAAAAETCHXfc8eSTTwZBkEqlYrHYmjVr+m3Tu3qT0VQq\nNWjQoPHjx/dpNQAAAEB03XHHHSeeeOLYsWPj8fjs2bP32muvftv0rgYcv/zlL/u0DgAAAOAj\no6qqauHChf25xV29RAUAAACIutra2lWrVk2cOHHQoEEHHnjgP//zP4fzu7u7Z8+evf/++zc2\nNn75y19et25dOH/jxo2nnnrqoEGDxowZs3LlyoaGhhdeeCEIghdffPHkk09ubm5ubGw8+uij\nn3nmmSAIxowZ85vf/GbevHnHH398NpsNL1E57bTTTj/99N4CbrrppiFDhvT09LzbFj+0XQ04\nPvOedrMIAAAAoH/MmjVr0qRJK1euPOKII7761a8mk8kgCKZMmfL73//+jjvuePzxx+vq6o45\n5pht27ZlMpkvfelLmUzm0UcfvfTSS6dOnRouHATBaaed1tXVde+99z700EOxWGzGjBlBEKxe\nvfoLX/jClVde+dhjj/Vu7owzznjssce6urrCyWXLln3lK1+prq5+xy3uzn7t6iUqBx100M6T\n6XR6/fr1L7/88he+8IUjjjhidyoAAAAA+s3pp59+xhlnBEHw/e9//2c/+9nrr7+ey+UefPDB\nN954o7m5OQiCe++9d999933yySd7eno2bdr01FNPDRgwIAiC9vb2c845JwiCfD4/a9asU089\n9YADDgiCYNOmTXPmzAmCoLKyMhaLxePxeDyezWbDzZ166qmFQuGxxx6bOHHipk2bVq5c+cMf\n/vDFF198xy2eeuqpH3q/djXgeOihh942p1AoLF++/Nxzz/3hD3/4oTcPAAAA9KcxY8aELwYP\nHhy+eP7553O53PDhw3uX6ejoeOmll9rb2w899NAw3QiC4KijjgpfVFRU/P3f//2KFSseeOCB\n3//+97/61a9isdi7ba6xsXHChAkPPvjgxIkT77///oMPPnjMmDH333//O25xd/ZrVwOOvxaL\nxU466aQpU6Z897vf/cUvfrE7RQAAAAD9o66u7m1zstnskCFDnn766Z1nDhgw4NEEInMAACAA\n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\nL7vssr333nvNmjVhuBAEwemnnz5z5swxY8Z85zvfWb58+bt98MwzzzzppJPC1xs2bLj22muv\nvPLKT3ziE52dne3t7el0OrxZRltb2w033HDuueeOGDFi0aJFQRCsX7/+nnvuCe9ZEp7jDhs2\nbMCAAWvXrh03blwQBGvXrq2rqxs+fHgQBIlEYv369WHO0tnZuXnz5qFDh37YNgEAAAAiZlcD\njmefffbcc8/tTTdCH/vYx84666wlS5a8xwcHDx7ce1vQTCYTBMHQoUMHDRo0ZMiQlpaWK664\nYvr06dXV1ffdd9/27duHDh0aj8eHDBkSBMHmzZurqqrC16F4PD5hwoS77rrr4x//eEVFxW23\n3XbCCSeEge6ECRN+/OMfz5gxo6mpaenSpc3Nze9xLw8AAADgI2ZXA463Pc2l1+5cD3bxxRff\nfvvtN998cyqVGjVq1OzZs993NPKkSZMymczChQvz+fzYsWPPOeeccP7kyZNjsdjixYu7urpG\njRo1Z86c3Xx8LgAAABAhuxpwtLS03H333RdddNHOgzjeeuute+655/DDD9/FlRx00EH/8i//\n0juZSCTOP//8d1t45MiRb7tDRxAEsVistbW1tbX1r+dPnjx58uTJu1gJAAAAlKBrRz9b7BKi\nalcDjiuuuOKoo4469NBD//7v/z58WMkLL7xw8803v/XWWw888EBfVggAAADwPnY14DjiiCOW\nL19+0UUXffe73+2d+elPf/qOO+4YM2ZM39QGAAAA5eWQky7bsyv886NX7NkVlqwP8NCpcePG\nrV279rXXXnvppZcKhcKBBx74yU9+smyf4QcAAACUjg8QcGzevPnOO+8cM2bMCSecEATBj370\no+7u7pkzZ5bgQ4kBAACAslKxi8u9+eabhx122Ny5c9etWxfOWb9+/bx580aPHv3aa6/1WXkA\nAAAA729XA465c+d2d3c/8cQTs2bNCufceOONK1eu7OjomDdvXp+VBwAAAPD+djXgePLJJ2fM\nmHHcccfFYrHemWPHjp0xY8aKFSv6pjYAAACAXbKrAceOHTvq6+v/en4ikeju7t6jJQEAAAB8\nMLsacIwZM+a+++7r7OzceWZXV9c///M/H3744X1QGAAAAMCu2tWA43vf+96//du//c3f/M2t\nt966atWqp556asmSJZ///OfXrVv3ne98p09LBAAAAEpEKpWKxWJr1qwJguCOO+548skn3zaz\nWHb1MbFHHXXUAw88MGfOnBkzZvTO3Hvvve++++7jjjuub2oDAAAASks8Hp89e/Zee+0VBMEd\nd9xx4oknjh07dueZxbKrAUcQBKeccsqJJ574zDPPrF+/PpPJDB8+vKWlJZFI9F1xAAAAQEmp\nqqpauHDhrszsZ7t6iUqoqqrqs5/97Fe/+tWpU6eOHTtWugEAAABRsWbNmiFDhqxcufJzn/vc\ngAEDjjvuuD/+8Y/hW2+99dbZZ5/9sY997BOf+MTZZ5/91ltvhfMfeOCBQw89tK6ubv/99//h\nD38YBEE2mw2vRhkzZsxvfvObefPmHX/88b0zTzvttNNPP713izfddNOQIUN6enq6u7tnz569\n//77NzY2fvnLX163bt0e37sPFnAAAAAA0dXe3j5lypQ5c+Y88sgjiUTi6KOP3rFjR6FQOPnk\nk//t3/7t3nvvXbp06UsvvTRhwoRCofDv//7vZ5xxxgknnPCb3/zmG9/4xty5c8M7boRWr179\nhS984corr3zsscd6Z55xxhmPPfZYV1dXOLls2bKvfOUr1dXVU6ZM+f3vf3/HHXc8/vjjdXV1\nxxxzzLZt2/bsrn2AS1QAAACASMtkMldfffWZZ54ZBMGYMWOGDRt25513HnrooWvWrHnllVf2\n33//IAh+9rOfHXjggStWrMhms7lc7mtf+9rw4cOPOOKIT33qU0OHDu1dVWVlZSwWi8fj8Xg8\nm82GM0899dRCofDYY49NnDhx06ZNK1eu/OEPf/jiiy8++OCDb7zxRnNzcxAE995777777vvk\nk0+eeuqpe3DXjOAAAACAMnLssceGLxKJxFFHHfWnP/1p3bp1n/zkJ8N0IwiCYcOG7b///uvW\nrfv85z9/yimnHHroof/zf/7Pn/zkJ0cfffSwYcPee+WNjY0TJkx48MEHgyC4//77Dz744DFj\nxjz//PO5XG748OEDBw4cOHDgXnvttWXLlpdeemnP7pcRHAAAAFCmKioqMpnMO87PZrO1tbX/\n8i//8tJLL/3sZz+7++67582b90//9E8TJkx473WeeeaZs2bNymQy9913X2traywWy2azQ4YM\nefrpp3debMCAAXtyT4zgAAAAgLLy61//OnzR3d39u9/9buTIkYcccsirr766YcOGcP5rr732\n7//+75/+9KefeOKJ+fPnH3jggZdeeulvf/vbE044YfHixe+7/pNOOimdTt9zzz2/+93vzj77\n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\nHDhww4YNY8eODefvvffeCxYs6Ov9AgAAAEpHnwccw4YNu/7663snf/vb37a3t3/qU58KgmDh\nwoXbtm278MILq6urH3jggfnz5998882NjY3hkq+88sqtt96682fDWGTw4MHhZH19fW1tbVtb\nWy6XC4Lg1Vdf/cEPfvDmm28OHz58+vTpO2clPT09P//5z3snt2zZ8rGPfSyVSvXhbkdK6TRF\nNpsNgiCTybjCqJ+VzjFQKBSCIMjn86VTUvkonTYPe/V0Ol1RUaZ3ws5kMuG/4TeiDIU/BXK5\nXOkclkVR5p1heBiUcwuEnWFPT094glSGes8Mi11I0egMQ4VCoQRboKenp9gl8A764yajoVwu\n98gjj9xxxx3jx48/5JBDXn/99VWrVi1ZsmTAgAFBEMydO3fq1Knr1q078sgj320N7e3tVVVV\nlZX/WXMikdixY0fY+y9evLi1tXXgwIH333//pZdeessttyQSiXCxrq6uq6++uvdThx122EEH\nHdTZ2dlXuxo1pdYUyWSy2CWUnVI7BnK5XKmVVA5Krc0/9N2aPjJK8GSun/X09JT56WM+ny+1\nL2b/0wI6w3Q6nU6ni11FMWUymXJOeYIgKBQKJdgV+G6Wpn4KOF577bXrrrvuzTffnDZt2skn\nnxwEwauvvprP52fOnNm7TDKZ3LRp03uspKGhIZPJ5HK53iendHd3NzQ0VFdXB0Fw/vnnjxo1\nKgiCAw44oLW1dfXq1V/84hfDxerr6+fPn9+7nj/+8Y81NTUNDQ17ei+jqnSaIpPJpNPpurq6\n3v9i+kfpHAOFQqGrqysej9fV1RW7lrJTOodBKpXKZrOJRKKcR3Ck0+na2tqdM/2yks/nu7u7\nq6urwx/x5amzs7OioqL3rzVlqLu7O5/Pl07X1P/CjK+cO8NsNptKpWpqaqqqqopdS3GEnWFV\nVVVNTU2xaymarq6uWCxWgp1hCZZE0D8Bx/PPP/+9733v8MMP//73vz9o0KBwZj6fb2pq2vkK\nlCAIEonECy+8cM011wR/GYt19tlnB0EwdOjQBQsWhJ/dtm1bc3NzEATJZDKVSg0aNCg8+xk2\nbFi4krq6uubm5rfeeqt3tdXV1RMnTuyd/I//+I+qqqra2tq+3OkoKZ2mKBQK6XS6qqqqnM9o\ni6KkjoGurq6KiorSKal8lE6bZzKZbDZbU1NTzlln2BmW7RltNpvt7u6Ox+Olc1j2vzDgKOcW\n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\nUeAAAAAAAACKR4EDAAAAAAAoHgUOAAAAAACgeBQ4AAAAAACA4lHgAAAAAAAAiucidwAAAACA\nAsxKai/DWjNtvcKlbc/aepUAUEMocAAAAAB4MHlKPDZXSYnHSTIgrCdBtgxct/UKqfQplC0K\nHEajcdu2bUeOHDEYDBEREZMmTdJoNDW7qBpcBQAAAAAAUBxbFDh27Nixf//+1157zcXFZdWq\nVWq1evLkyTW7qBpcBQAAAAAAUJxaL3CUlpYeOHBgwoQJ3bt3F0Lo9fpVq1aNHTvW3d29phbl\n4uJSU6sAAAAAAABKVOsFjoyMjNzc3A4dOkhvO3ToUFhYePXq1datW+v1+k2bNp06dSo/Pz8k\nJGTKlCmBgYHmD+p0uuzs7EaNGj1wUV5eXtZWUdutAwAAAAAA9qDWCxw5OTlCiMcff1x66+Xl\n5e7unpubK4RYvnx5Tk7O9OnTtVrt7t27Y2NjV69e7ePjI835+++/r127Ni4u7oGL0uv11lYh\nycvLmzBhgvlt48aN69Spc/fu3VprtMKQCjJABgRJIANkgAyQASEESSADZIAMCCFIQhUykJ+f\nb5tIUC21XuDIy8tzdXV1cfn/K/L09Lx3796NGzcSExM3btzo5+cnhJg1a9akSZMuXboUFhZW\n3UWVlJRUOP0RI0/cPOMRl1BdRqPRZDLZ1eNRbZwEk8lkNBrVarVKpbLleitBBmx/IBgMBiGE\n/RwIZIDOUNAVyHQgkAHh3F2BvWVACBEbeMSWq5O6AjJgV12BjTMg7K8zlCUDws66AtizWi9w\neHt7l5SUGAwG805ZWFjo7e2dnp5uNBqnTZtmnrOoqCgzs7Jf+ra2KE9Pzwqnmz/o6+u7d+9e\n89svvvjCy8urTp06NdXGmpKXl1dcXOzn56dWq+WORR5FRUUFBQXe3t5arVbuWORRUlJy7949\nd3d3T09PuWORh8lkys7OdnV1lUqfzunu3btGo9EO+yibyc/P1+v1vr6+Tns2o9Pp7t+/7+Xl\n5ebmJncs8igtLc3NzXVzc/Py8pI7FtncuXPHxcXlsccekzsQ2eTm5paWljpzZ1hQUFBUVOTj\n42P5bzynotfr8/PzPT09nfbJegaD4e7du1qt1vKrjbPJzs5Wq9V22BWY7zyAXan17lLaF3Ny\ncvz9/YUQRUVFOp2uTp06ubm5vr6+lnegCCE8PT0vXLiwePFiIYTBYNDpdOPGjRNCNG7ceMmS\n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\nVVFcXCy9kH2/rT01eC7kwFlyGFUcys17fnnlB5fyrA2aSmTZsZfv5B2mV6z6iGa5cd3c3Go9\nMigZl/HYiPnnu/V6fUpKSpMmTRo3bnzr1q3bt29L02/dunXz5s0nn3zS2nTpbZ8+fdq2bduj\nR481a9aUlpbaviGPrpIGdu7cuaSk5Pjx45cuXYqMjBRCBAYG5uXl6fV6qXar1WpXrVqVnZ0t\nZwNqgrV2JScnX79+PS4ubvjw4SEhIeauPDAw8PLly4WFhdLbCxcuWN6KbOcCAwP/+OMPc/CX\nLl2yNlu1cqI4SUlJmzZtatCgwciRIz/++OP27dt///33ljNUfuxbCg4Orlev3oYNG/Lz87t3\n726L6P+vwMDAP//8s6CgQHp78ODB6dOnW5u5iluwkp2/8nVVsZd4YP5rm7UDobpjgaJ7gyoq\nM9I56kBQ3v3796UXV65ckV7Ivt/WrFo6F3KwLDmkygeC8nt+VVR90HQ8DtMrWhvRnHnj4tFR\n4LAFFxeX9evXnzx58uLFix999JEQolevXq1bt27evPmSJUuSk5OTk5OXLFnSvHnz0NBQa9Mt\nFzhlypQ7d+588803MjXokVTSQHd3986dO69bty40NNTf318IERQU1KFDh4ULF54+ffrcuXNL\nly69fft248aN5W7Eo7LWLk9PT71ef+zYsZycnJ9++mnz5s16vT47O/vZZ5/VarUffvjhhQsX\nfvrppy+++MLytwbsXLdu3Xx9fZctW5aamnrq1Kldu3aJiv59Xd2cCCFUKlVWVpb0uE37p1ar\nd+3atXv37t9//z0hISE1NVX6BQFzK6py7Euku1SOHDnSpUsXWf5j06VLl8cff3zp0qWpqanH\njx/fvn17JTdKVLIFqzKbtXWZ81bFXsJa/m3G2oFQ3bFA0b1BtZhHOkcdCCy5ubn5+vru2LEj\nLS3tzJkz+/btk6Y/sN+QNerqqb1zIdmP7tqmxM1dhrUe3tqeL6rQ6qoPmvbs4Tauw/SK1ka0\nh9i4DnCYoKZoHO/hZPYmJyfn9OnT//jHP7Zv337gwIE6deq8/fbbdevWValUXbt2vXz58u7d\nu0+ePBkcHDxjxgx3d3dr0/Py8vbv3z98+HCtVuvh4eHq6rpt27aePXsq6IK0bdu2PffccwEB\nARU2UJpHpVIdOXJkzJgxTZs2laaEhYVlZmbu3bv32LFjjRs3njlzpkLvuNu+fXuvXr3MN1VW\n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\nAAAAAABQvP8Hc1P0Cne2UjwAAAAASUVORK5CYII=", "text/plain": [ "plot without title" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "g + \n", " geom_col(aes(y=n, fill = label)) + \n", " scale_fill_manual(values=c(\"#74d130\", \"#274a7c\"))" ] }, { "cell_type": "code", "execution_count": 198, "metadata": { "collapsed": false }, "outputs": [ { "data": {}, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABaAAAAJYCAIAAAAbpNZlAAAACXBIWXMAABJ0AAASdAHeZh94\nAAAgAElEQVR4nOzde3hU1b3/8TUzmcn9hgQj4ZJSYig2KimIpTkKFAhSoZ7yqFTkHgxSqoCl\nKkqEAwHhaAAVpKWKclQQLeCxUi0erJLzk0espgKVcLHIxQTIPXOf2Xv//tin0xRJgLlkzU7e\nr4fnYWZnstZ3Lllr55O91zZpmiYAAAAAAACMzCy7AAAAAAAAgFARcAAAAAAAAMMj4AAAAAAA\nAIZHwAEAAAAAAAyPgAMAAAAAABgeAQcAAAAAADA8Ag4AAAAAAGB4BBwAAAAAAMDwYmQXIMeM\nGTOqq6tlVwEAQPSKiYnZtGlTly5dvv2lpUuX7tu3r/1LAgDAKGJiYh5//PFBgwbJLqRz6aQB\nx/nz55988snY2FjZhQAAEI3WrFnzySef+P3+i361rq5u1qxZubm57VwVAACGsGPHjjfeeMPt\ndssupNPhFBUAAAAAAGB4BBwAAAAAAMDwCDgAAAAAAIDhEXAAAAAAAADDI+AAAAAAAACGR8AB\nAAAAAAAMj4ADAAAAAAAYHgEHAAAAAAAwPAIOAFHq3XffPXDggBDC6/UOGzassrJSdkUAAESj\nlhMlsyeAzoyAA0CUeu+99/RdNIvFMn78+LS0NNkVAQAQjVpOlMyeADqzGNkFAMAlWCyWOXPm\nyK4CAIAoddGJktkTQCfEERwAgjRq1KhDhw6VlJSMHTt24sSJH330kb7d7XY/99xzEyZMGDNm\nzMMPP/z111/r28+fP//YY4+NHTu2uLj4iy++uO222/7+978LIU6dOvXoo4/ecccdY8aMeeCB\nB44cOSKEKC4urqio2Lhx40MPPaQoin6Q7WOPPfb4448HCti5c+dPf/pTv9/fWo8AAES5ysrK\nn/70p1988cXs2bNvv/32uXPn6pOjEKKhoaG0tPRnP/vZ+PHjS0tLGxoa9O0fffTRjBkzCgsL\nJ0yY8PrrrwshAhMlsyeATo6AA0DwysrKhg8f/swzz+Tm5i5btszj8QghVqxYUVlZ+cgjjzz1\n1FOxsbFz585tbm5WFGX+/Pl+v//JJ5+89957V65c6fV69UYee+wxl8tVUlKybNkyk8n09NNP\nCyHWr19/ww03zJgxY9WqVYHuhg0btn//frfbrd/985///OMf/zgmJuaiPbb7iwEAQDAcDseT\nTz555513lpaWxsXFPfDAAw6HQ9O0Rx999NSpUyUlJSUlJadPn37kkUc0TauqqvqP//iPQYMG\nrV279t///d83bNign5CiY/YE0MlxigqA4BUUFAwdOlQIMW3atA8++KCmpkZV1f/93/998803\n9ZN+S0pK7rrrrgMHDvj9/tra2g0bNiQmJgohnE7nk08+KYRQVXXcuHFDhgzp3r27EKKmpmbd\nunVCCIvFYjKZzGazxWJRFEXvbsiQIZqmffLJJ7fcckttbe0XX3wxa9asU6dOXbTHIUOGyHlR\nAAC4EoqiFBUVDRs2TAiRm5v785///L333vvud7975MiR11577eqrrxZCPPHEExMnTvzrX/+q\nqqqiKGPHjs3KysrNze3du3dGRkagKWZPAJ0cAQeA4OXm5uo3UlJS9Bt///vfFUW59957A49x\nuVxnzpxxOBzf/e539XRDCPH9739fv2E2m3/605/+9a9/3bt375EjR/bv328ymVrrLiEh4eab\nby4vL7/llls+/PDDnj175ubm7t2796I9hveZAgAQOTfeeKN+Iy4u7rrrrvv666+tVmtmZqae\nbggh9NsnT54cPXr0kCFDZsyYMXjw4Pz8/BEjRiQmJgayjIti9gTQeRBwAAhebGzsBVv8fn9q\nauqGDRtabkxKSnr99ddbJheB2y6Xa+7cuX6/f/jw4XfccUdBQcGaNWva6HHYsGFlZWWKonz4\n4YejRo0ymUyt9RjSEwMAQBKz2ez3+7+93WQyKYpis9lKS0vPnDnzwQcf7N69e+PGjQsXLhw8\neHDbbTJ7AugkWIMDQDhlZ2c3NjZ6PJ7MzMzMzEybzVZWVnb+/PnevXsfP37c4XDoDzt48KB+\no6Ki4uTJk7/5zW8mTpyYl5fX9t+ghBA333yzz+d7//33Dx06NGLEiDZ6jOjTBAAgjCoqKvQb\nbrf70KFD2dnZPXv2PHv27NmzZ/XtZ8+era6u/s53vvP555//7ne/6969+7333vvcc8/94Ac/\n+OMf/3jJ9pk9AXQSHMEBIJz69OkzaNCghQsX/uIXv7DZbK+88kp9fX2vXr2ysrJefPHFpUuX\nTpo0qb6+fsuWLUIIs9mckJDgdrt379590003HT58+MUXX3S73TU1NV27dhVCnDlzpq6uLjU1\nNdB+fHz8zTffvG7duuuvv14/cLe1HmW9AgAAXKl169aZzeYuXbps2bLF6/XedtttCQkJOTk5\nixcvnjVrlhBiw4YNOTk5119//RdffPHqq68mJiYOGjTo66+//tvf/jZ27NgLWmP2BNBpcQQH\ngDB74oknBgwYUFZWtnjx4qSkpJUrV1osFpvN9tRTT6mq+vDDD2/btu2Xv/ylECIlJeX666+f\nOnXqxo0bp02btnv37lWrVmVlZS1atEgIMXr06PLy8rKysgvaHz58eHNzc2FhYds9tudTBgAg\nFAsWLHjllVceeeQRl8u1du3apKQks9m8YsWKrKysJUuWLFmypEePHk8++aTZbL7xxhvnzJnz\n9ttv33///b/97W9HjBhxzz33tGyK2RNAZ2bSNE12DRKMGzeutLT028sHAIiQs2fPfvzxx2PH\njtV3nioqKhYsWPDuu++yLwVEpzVr1nzyySe7du3q1q3bt786b9684cOHB5YZBhC0ysrKWbNm\nvffeezabTXYtAMJmx44db7zxxurVq//t3/5Ndi2dC6eoAGgPsbGxv/nNb06fPv2zn/3M7XZv\n2LChsLCQdAMAAABAuBBwAGgPaWlpTz755IYNG/7whz+kpaX98Ic/nDlzpuyiAAAAAHQcBBwA\n2skNN9zw/PPPy64CAIAokpub+8EHH8iuAgA6CBYZBQAAAAAAhkfAAQAAAAAADI+AAwAAAAAA\nGB4BBwAAAAAAMLzOu8jokiVLTCaT7CoAAIhG586da/sBv/3tb+Pi4tqnGAAAjKWhoUF2CZ1U\nJw046urqvF6v7CoAAIheZrNZUZSLfunrr78+e/ZsO9cDAICBmM3m+vp62VV0Op004Lj66qtf\neeWV+Pj40Juqq6sTQnTp0iX0poLT2Njo8/m6du0qq4Dm5maPx9OlSxezWc4ZTw6Hw+VypaWl\nxcTI+Ty7XC6Hw5GSkmKz2aQU4PF4mpubk5KSZP011efzNTY2JiQkJCQkSClAUZT6+vq4uLik\npCQpBWiaVltba7VaU1NTpRQghKitrTWbzenp6bIKqK+vV1X1qquuklWAPhheddVVso7O0wfD\n9PR0i8UipQB9MExNTbVaraG39utf/3rPnj2tPZd+/fqVlJTceOONoXfU1NTk9XolTiJ2u93t\ndkucRJxOp9PplDiJuN1uu93OJCJ9ErHZbCkpKVIKEELU1tZaLJa0tDRZBdTX12uaxh51h5lE\ngqDvUScnJ8fGxkopQN+jTkxMDMsviS+88MLzzz8vcces02INDgAAAAAAYHgEHAAAAAAAwPAI\nOAAAAAAAgOERcAAAAAAAAMMj4AAAAAAAAIZHwAEAAAAAAAyPgAMAAAAAABgeAQcAAAAAADA8\nAg4AAAAAAGB4BBwAAAAAAMDwCDgAAAAAAIDhEXAAAAAAAADDI+AAAAAAAACGR8ABAAAAAAAM\nj4ADAAAAAAAYHgEHAAAAAAAwPAIOAAAAAABgeAQcAAAAAADA8Ag4AAAAAACA4RFwAAAAAAAA\nwyPgAAAAAAAAhhcjuwAAANARqNXXBvFdSfp/54QaVKfmzCNBfR8AAOiAOIIDAAAAAAAYHgEH\nAAAAAAAwPAIOAAAAAABgeAQcAAAAAADA8Ag4AAAAAACA4RFwAAAAAAAAwyPgAAAAAAAAhkfA\nAQAAAAAADI+AAwAAAAAAGB4BBwAAAAAAMDwCDgAAAAAAYHgEHAAAAAAAwPAIOAAAAAAAgOER\ncAAAAAAAAMMj4AAAAAAAAIZHwAEAAAAAAAyPgAMAAAAAABgeAQcAAAAAADA8Ag4AAAAAAGB4\nBBwAAAAAAMDwCDgAAAAAAIDhEXAAAAAAAADDI+AAAAAAAACGR8ABAAAAAAAMj4ADAAAAAAAY\nHgEHAAAAAAAwPAIOAAAAAABgeAQcAAAAAADA8Ag4AAAAAACA4RFwAAAAAAAAwyPgAAAAAAAA\nhkfAAQAAAAAADC9GdgFyqKra2Njo8XjC0pQQoqGhIfSmgqMoitwC9FegqalJbgHNzc0mk0li\nAQ6Hw+l0SilA0zQhhMvlcrvdEgtwu91er1dKATqv1yvxB0EI4ff7JRagaZqiKHKHAk3TpA+G\njY2NcgtoamqSOxbZ7fawFODz+dr4qt/vt9vtF7zdKaH3euVC/8jpb1xnnkT0AphEpE8iPp+v\nk08ionPvUXewSSToAhwOh8vlklJAYI86LL8kyhpR0UkDDrPZnJKSEh8fH3pT9fX1QojU1NTQ\nmwpOU1OTz+eTWIDdbvd4PMnJyWaznAOCnE6ny+VKSkqKiZHzeXa5XE6nMyEhwWazSSnA4/HY\n7fa4uLi4uDgpBfh8vqampri4uLD8TAVB3yez2WyJiYlSCtA0ra6uLiYmJiVFyq94QghRV1dn\nNpslDgUNDQ2qqkofDFNSUmTtmQUGQ4vFIqUAfTBMTEy0Wq2ht9Z2IzExMYmJiRe83ZqMfbnQ\nP3IOh8PtdkucRPQ3TuIk4na7HQ4Hk4j0ScRqtSYnJ0spQAhRV1dnsVjkTiKapkmfRKJhj7pj\nTCJBCOxRx8bGSikgsEcdlrFI1rNAJw04hBAmkymMO8Gy9qejqgC5NUgsQO+XAoS8z6H0Ar5d\nCQVILKDTjkXtXMC3O9LaodeLlRGudjr5GC69AMEkQgEU0JkmkYt23ZEKkP5Z6rRYgwMAAAAA\nABgeAQcAAAAAADA8Ag4AAAAAAGB4BBwAAAAAAMDwCDgAAAAAAIDhEXAAAAAAAADDI+AAAAAA\nAACGR8ABAAAAAAAMj4ADAAAAAAAYHgEHAAAAAAAwPAIOAAAAAABgeAQcAAAAAADA8Ag4AAAA\nAACA4RFwAAAAAAAAwyPgAAAAAAAAhkfAAQAAAAAADI+AAwAAAAAAGB4BBwAAAAAAMDwCDgAA\nAAAAYHgEHAAAAAAAwPAIOAAAAAAAgOERcAAAAAAAAMMj4AAAAAAAAIZHwAEAAAAAAAyPgAMA\nAAAAABgeAQcAAAAAADA8Ag4AAAAAAGB4BBwAAAAAAMDwCDgAAAAAAIDhEXAAAAAAAADDI+AA\nAAAAAACGR8ABAAAAAAAMj4ADAAAAAAAYHgEHAAAAAAAwPAIOAAAAAABgeAQcAAAAAADA8Ag4\nAAAAAACA4RFwAAAAAAAAwyPgAAAAAAAAhkfAAQAAAAAADI+AAwAAAAAAGB4BBwAAAAAAMDwC\nDgAAAAAAYHgEHAAAAAAAwPAIOAAAAAAAgOERcAAAAAAAAMMj4AAAAAAAAIZHwAEAAAAAAAyP\ngAMAAAAAABgeAQcAAAAAADA8Ag4AAAAAAGB4BBwAAAAAAMDwCDgAAAAAAIDhxbRbT3v37n3r\nrbdOnjyZm5s7a9asrKys4NpRVXXLli179uxRFKWgoGDatGkWiyW8XQAAAAAAAGNppyM4Pvro\no7Vr144cOXLhwoV+v3/ZsmWqqgbX1LZt2955550ZM2bMnj177969L7/8cti7AAAAAAAAxtIe\nR3BomrZt27YJEyYUFhYKIbp167Z27dqqqqogjrDw+/27du2aNGnSkCFDhBAej2fdunX33HNP\nbGxsuLoAAAAAAACG0x4BxzfffHPy5MmCggL9bvfu3VeuXKnf9ng8mzdv3rdvX3Nzc//+/WfM\nmNGzZ8/AN7rd7tra2pYhxenTpxsaGvLz8/W7+fn5Tqfz+PHjaWlprXUBAAAAAAA6vPY4RaW2\ntlYIceLEifnz599zzz1PPPHEqVOn9C+tWbPm2LFjc+fOXbp0aWxs7MKFC5ubmwPf+NVXXz39\n9NMtm6qrqxNCXHXVVfrdxMTEuLi4hoaGNroAAAAAAAAdXnscwdHQ0CCE2LRp0+TJk9PS0n7/\n+98/9thjGzZsqK+v//jjj19++eXU1FQhxIIFC6ZNm/bll1/edNNNrTXV1NRktVpjYv5ZdkJC\nQmNjo6IoF+0iISFBf9hbb721du3awHclJibW1dXFxcWF/uw0TRP/CHEkkl5AfX293AIaGxvl\nFtAym5PC4XA4HA6JBbhcLpfLJbEAj8fj8XgkFuDz+ST+JGqapiiK3AKE1LFIL0DPwSUWoE95\nEgtoamoKS2ter7eNr/r9/sbGxgve7vSwdHyFQv/I6a+bxElEL0DiJKIXwCTCJOL3++UWYDKZ\npE8i0guor683mUwSC2hsbJRVgK65udlut0sswOFwOJ3O0NsJSyMIQnsEHDabTQgxZ86cvLw8\nIUSfPn0mT568b9++2NhYVVWLi4sDj3S5XN98800bTSUlJfl8PkVRAldOcTqdSUlJrXUxfPhw\n/WFWqzU5OTnQjqqqZrPZbA7DASx6thKWpoKjr6XamQvQNE3TNOkFmEwmiRNSJy9ACKEoivQC\nhNQfBApQVVXuUKAXIPFz2M4FhGsaDb2MEFvobG9cFBYgGMOjowCTydSZ9yejZBIxm81yhwKJ\nBQR26aXv0IblYyA3J+rM2iPgSE9PF0JkZ2frd+Pj4zMyMs6fP9+9e/eUlJSysrKWD05ISDh4\n8OCKFSuEEIqiuN3uiRMnCiF69OixcuVKvam6urqMjAwhhMvlcrvd6enpesDx7S4CzY4ZM2bM\nmDGBu+PHj09LS4uPjw/92el/LdQLk6KxsdHn80ksoLm52ePxpKamypoSHA6Hy+VKTk5ueWhP\ne3K5XA6HIxC0tT+Px9Pc3JyQkBCWg5KC4PP5Ghsb4+LiAsdMtTNFUerr6202W1JSkpQCNE2r\nra21Wq368WhS1NbWms1miUNBfX29qqrSB8O0tDRZuxSBwTAQwbezwGBotVpDb63tAS0mJiY5\nOfmCt1utDr3bKxb6R85ut7vd7pSUFFmTiNPpbPnXmvbndrvtdjuTSGxsrPRJJCUlRUoBQoja\n2lqLxZKWliargPr6ek3TpE8i0bBH3TEmkSDoe9SJiYmxsbFSCgjsUYfll8SwNIIgtMdc3rt3\n74SEhKNHj+qLg9rt9nPnzvXo0SMrK6upqcnj8egLizY0NKxevXr69OnXXnutfjrJ0aNHX3vt\ntSeeeEIIof+oZ2dnp6amVlRUjBw5UghRUVERHx+fk5MjhLhoF+3w7AAAAAAAgHTtEXDExcWN\nGTPmueeemzlzZkpKypYtWzIyMm666Sar1Zqfn7906dKioiKbzfbGG2/U19f36NHDYrF07dpV\nCHHu3Dmr1arf1lksljFjxrzyyiuZmZlms/mFF14YNWqU/geHi3bRDs8OAAAAAABI105HY06a\nNMlkMm3atMnhcOTl5c2bN08/9unXv/71iy++uH79erfbnZeX9+CDD17yoKwJEyb4fL41a9ao\nqlpQUDB16tS2uwAAAAAAAB1eOwUcJpNp0qRJkyZNumB7QkLCnDlzWvuu/v37X7BCh97U5MmT\nJ0+efJldAAAAAACADk/++ucAAAAAAAAhIuAAAAAAAACGR8ABAAAAAAAMj4ADAAAAAAAYHgEH\nAAAAAAAwPAIOAAAAAABgeAQcAAAAAADA8Ag4AAAAAACA4RFwAAAAAAAAwyPgAAAAAAAAhkfA\nAQAAAAAADI+AAwAAAAAAGB4BBwAAAAAAMDwCDgAAAAAAYHgEHAAAAAAAwPAIOAAAAAAAgOER\ncAAAAAAAAMMj4AAAAAAAAIZHwAEAAAAAAAyPgAMAAAAAABgeAQcAAAAAADA8Ag4AAAAAAGB4\nBBwAAAAAAMDwCDgAAAAAAIDhEXAAAAAAAADDI+AAAAAAAACGR8ABAAAAAAAMj4ADAAAAAAAY\nHgEHAAAAAAAwPAIOAAAAAABgeAQcAAAAAADA8Ag4AAAAAACA4RFwAAAAAAAAwyPgAAAAAAAA\nhkfAAQAAAAAADI+AAwAAAAAAGB4BBwAAAAAAMDwCDgAAAAAAYHgEHAAAAAAAwPAIOAAAAAAA\ngOERcAAAAAAAAMMj4AAAAAAAAIZHwAEAAAAAAAyPgAMAAAAAABgeAQcAAAAAADA8Ag4AAAAA\nAGB4BBwAAAAAAMDwCDgAAAAAAIDhEXAAAAAAAADDI+AAAAAAAACGR8ABAAAAAAAMj4ADAAAA\nAAAYHgEHAAAAAADGMHr06DvuuOPw4cMjR45MTEzMzMwsKipqbGyUXVdUIOAAAAAAAMAwqqqq\nhg0blpOTs2bNmltvvfWFF16YP3++7KKiQozsAqTx+/1+vz+MrYWrqSulaVqUFGA2y8nLVFUV\nQiiKIqX3lgXIehf0566qaqctQH8LJBag/xRomibxJ1F6AdEzFplMJokFKIqi32h/gbEoLK9A\n289C07RvD3pS5oDQP3JMItKHUCYRJhERTZOI9AI6xiQSSgEdYyzSn07kfPLJJ2vXrn3ggQeE\nEEVFRSdOnNi9e3dEezSKThpwqKrqdrvD1ZTJZHK5XGFpLbgChBASC9DHArfbLWs01Mcgj8cj\nqwD9FfB6vXL3zLxer6wddL0Av98v63MY+MVS4g+C9AL0F0FuAZqmRcNgKHcsiobB0Ofzhd5a\n2+OJqqoej+eCtzsx9F6vXOgfOf2ZSpxE9DdO4iQSmMVkTSKB3+uYROQWIHcMlz6LRcketfSx\nKFyTSBCkj0X6Z8Dn84Ulm4j0y2iz2YqLi/XbJpPphhtuOH78eER7NIpOGnCYzeakpKT4+PjQ\nm9I/u8nJyaE3FZzGxkZVVSUW0NzcrChKUlKSrCM4HA6Hy+VKSEiIiZHzeXa5XH6/Pz4+3maz\nSSlAn4ri4uLi4uKkFODz+RobG202W0JCgpQCFEXxer1WqzUpKUlKAZqmeTyemJgYiT+JXq/X\nbDZLLKC+vl7uWBQYDGXtGjY3N3s8nsTERIvFIqWAwGBotVpDb63tEdVisSQkJFzwdquO0Lu9\nYqF/5Ox2u6IoEicRp9PpdDolTiJut9tut8udRLxeL5OI3EmktrZW+iSiaVo0TCKyCtD3qDvM\nJBKEwB51bGyslAL0PerY2Niw/JIY6WfRq1evll3I+kUsCvFCAAAAAABgGLJioOhHwAEAAAAA\nAAyPgAMAAAAAABgeAQcAAAAAADA8Ag4AAAAAAGB4BBwAAAAAABjDu+++e/DgwZZbNmzYUFNT\nI6ueqELAAQAAAAAADI+AAwAAAAAAGB4BBwAAAAAAMDwCDgAAAAAAYHgEHAAAAAAAwPBiZBcA\nAAAAAAAuRW1UfX8Ne6smSw9TTJ+wNysFAQcAAAAAANFO8x/2100Le7OWxOmWlMfC3qwUnKIC\nAAAAAAAMj4ADAAAAAAAYHgEHAAAAAAAwPAIOAAAAAABgeCwyCgAAAABAtFOF8GlaBBrWLBFo\nVAoCDgAAAAAAop2mCX8EAg5LJDITSQg4AAAAAACIdpoQvgg025FCgY70XAAAAAAA6Jg0EZEj\nONSInPYiBwEHAAAAAADRLkJHcCgRaFMWAg4AAAAAAKKdJrSIHMER9hblIeAAAAAAACDacQTH\nJRFwAAAAAAAQ7ViD45IIOAAAAAAAiHaaEP4INMsRHAAAAAAAoP2omvBppvA3K8LfpiwEHAAA\nAAAARDtNmHzCHPZmFQIOAAAAAADQbjRh8mmWsDerROCoEFkIOAAAAAAAiHaaEBEJOCJwVIgs\nBBwAAAAAAEQ7TZj8EQg4VI2AAwAAAAAAtBdVmHyCIzjaQsABAAAAAEC007TIrMHBIqMAAAAA\nAKDdRGgNDk5RAQAAAAAA7SdCa3AoBBwAAAAAAKDdaJFZg0PlFBUAAAAAANBuNBGhNTg4ggMA\nAAAAALQXTRP+CJxOomocwQEAAAAAANqLyhEcl9JxngkAAAAAAB2Vvsho2P+1fQTH1q1bb775\n5uTk5BEjRhw5ciTo4hVFWbRoUe/evbOysubNm+fz+cLehSDgAAAAAAAg+umXiQ37vzaO4Niy\nZcv06dOnT5++fft2r9c7btw4RVGCK760tHTdunVlZWXPP//81q1bH3nkkbB3IThFBQAAAACA\n6KdpJr8agauoqBcPODRNKy0tLSkpue+++4QQ2dnZ06ZNO3bsWG5u7pV24fV6169fX1paOn78\neCGE0+ksLi5esmRJYmJiuLrQcQQHAAAAAADRThMmn2YO+z+llcvEHjly5NChQ3feead+Nycn\np7y8XI8enE7ngw8+2Lt37+Tk5Ntuu+3LL79s+Y12u72ysrLllsOHD589e3b06NH63dGjRzc1\nNX3++edtdBEcAg4AAAAAAKKdJkR7rsFx5swZIcSBAwcGDhzYpUuXwsLCv/3tb/qXpkyZ8pe/\n/OWll17avXt3fHz8rbfeWldXF/jGioqKiRMntmyqqqpKCJGVlaXfTUtLS0pKqq6ubqOL4HCK\nCgAAAAAA0S7GFHt71i9abjnc9Jcvm/ZfUSPptm5Du/3sX5o1Wy/6yLNnzwohFixYsGLFim7d\nuq1atWr48OGVlZXV1dU7duyoqqrKyMgQQmzdurVnz57l5eXjxo1rrdOamprY2FibzRbYkpKS\ncv78eb/ff9EuUlNTr+hJ/fO5BPdtAAAAAACg3XhV3xunNn5r85WtynHeU3tBI7dk3J6ffpFH\nxsfHCyE2btw4dOhQIcSAAQMyMzN37tyZmJioKEpOTk7gkc3NzceOHWuj0/T0dI/H4/P5rNb/\nC1OamprS09Nb62LKlClX9KQCCDgAAAAAAIh2mhB+LfyrTLS2BkdmZqYQIi8vT7+bnJzcq1ev\nU6dO9e3bt2vXrvv3/8uRI6mpqR9++KG+hqjP53M4HF27dhVC9OvXr7y8XG+qqtDWbxgAACAA\nSURBVKqqV69eQojm5ma73X7NNdfExcVdtIugnwtrcAAAAAAAEO00YfJr5rD/a20Njry8vNTU\n1ECQUV9ff+LEidzc3P79+9fU1Lhcruzs7Ozs7Pj4+OLi4tOnTw8ePLiioqKiomLTpk39+/fX\nb7/55pt6U926ddu9e7fe1Pvvv5+cnDxo0KDWugj6JeIIDgAAAAAAop2mCb8WgcvEtnLcQ2Ji\n4uzZs2fOnLl27dqMjIzFixf36tVr3LhxsbGxhYWFY8eOXb16dVxc3PLly6urq/v162e1Wnv0\n6CGEOHHihM1m02/rrFbr/fff//jjj/fp0ycmJmb+/PlFRUWJiYlCiIt2EfRzIeAAAAAAACDa\nacKkqOE/CUNVL34EhxBi2bJlJpNpwYIFDQ0Nw4YN27x5c2xsrBBi27ZtDz300KxZsxwOx9Ch\nQzdt2hRYXKM1JSUlXq936tSpiqLcddddq1ataruL4BBwAAAAAAAQ7SK0BofayhocQgiz2Vxa\nWlpaWnrB9pSUlI0bv73c6f8pKCj49NNPv93U8uXLly9ffpldBOdyX50JEyZc9IK0e/bsKS4u\nDkspAAAAAADgojTN5NcsYf+nRiA0keUSR3DU1NToN15//fWf//zn3bp1a/lVVVX/+Mc//td/\n/ddvfvObSBUIAAAAAECnpy8yGvZm2ziCw3AuEXBkZGQEbt9xxx0XfcywYcPCWREAAAAAAPhX\nmhD+CKzBobRyFRUjukTAsXr1av3GvHnzfvGLX/Tt2/eCB1it1rFjx15+f4cPH3744Ydfeuml\n9PT0Kyo0QFXVLVu27NmzR1GUgoKCadOmWSz/t5Ds3r1733rrrZMnT+bm5s6aNSsrKyu4LgAA\nAAAAiCqaFpkjODpPwDF37lz9xs6dO4uKim688cZQOnO73WVlZZqmhdLItm3b3nnnnTlz5sTE\nxKxbt85sNk+fPl0I8dFHHz3zzDMzZ868+uqrX3/99WXLlulfDaUvAAAAAACigSaEwikqbbrc\nq6j8+c9/Dr2zF154IZQrvggh/H7/rl27Jk2aNGTIECGEx+NZt27dPffcExsbu23btgkTJhQW\nFgohunXrtnbt2qqqKg7iAAAAAAB0CBG5TKzW+mViDedyA46Ghob58+e///77Tqfz218NrEXa\nhk8++eTTTz998MEHS0pKAhs9Hs/mzZv37dvX3Nzcv3//GTNm9OzZM/BVt9tdW1vbMqQ4ffp0\nQ0NDfn6+fjc/P9/pdB4/fjwtLe3kyZMFBQX69u7du69cufIynxoAAAAAAFFO0ziC4xIuN+B4\n6KGHNm3aNHjw4Ouvvz6I8z4aGxufffbZefPmJSUltdy+Zs2aurq6uXPn2my27du3L1y4cP36\n9cnJyfpXv/rqq9/97ndlZWWBx9fV1QkhrrrqKv1uYmJiXFxcQ0ODoihCiBMnTqxataq6ujon\nJ6eoqKhlVnL69OnDhw8H7qqq6vF4wnICi37GjcfjCb2p4KiqGg0FeL1ek0nOD4b+7nu9Xv1G\n+/P7/UIIn88X4ulXIRbg9/tlfQz0V15RFFkF6B9CiQXob70+sEgpIFCGxAKiZzCUPhbJOjtS\nL8Dn8+kvRYjabkTTNJ/Pd8HbbQ291ysX+keOSYRJhEkkUIbcSURuAdGzR90xJpEgBAZDKb0H\nug7XYKg/nbDThPBH4GiLTrQGR8Dbb7999913b9myJYgdR03Tnn322SFDhuTn5x87diyw/cyZ\nMx9//PHLL7+cmpoqhFiwYMG0adO+/PLLm266qbWmmpqarFZrTMw/y05ISGhsbNR/IDdt2jR5\n8uS0tLTf//73jz322IYNGxISEvSHffzxxy2P6cjMzLTb7WH82DU3N4erKYMWYLfb5RZw0WOL\n2pPL5ZJbgNvtdrvdEgvweDxy98x8Pp/ESVEIoSiK3J9ETdOkDwXSC5A+FjkcDrkFhGswbPun\nSVEUp9N5wdvdJSwdX6FwfeSYRJhEpE8ifr9f7hAqfRYTUTCJSC+gw0wiQeswY5HX6w29kW/T\nhCkiR3B0woDDbrePGDEiuD+L7dmz5+TJk7/61a8u2H7ixAlVVYuLiwNbXC7XN99800ZTSUlJ\nPp9PUZTAlVOcTmdSUpLNZhNCzJkzJy8vTwjRp0+fyZMn79u3b/jw4frDfvCDHyxcuDDQzubN\nmxMTE+Pj44N4OhfQh6HExMTQmwqOy+VSFOWCQ2Pak9vt9vv9iYmJsv5q6vV6vV5vQkKCrMBb\n/zNmfHx84GPZzvx+v9vtjo2NtVql/AFVKIricrlsNpv+k9j+VFV1Op1WqzXEVX6Cpmmaw+Gw\nWCxhGVWC43A4TCZTINVtf06nU1VViWORPhhKHIv0wVDiWOTxeHw+X7jGopZ/S/g2s9kcHx9/\n4dvdEHq3Vyz0j5z+ukl84/RZLC4uru3XPHL0WYxJROIkIoSw2+0xMTFxcXGyCnA4HPrPtawC\nnE6npmnsUXeYSSQI+lgkcTDU96jDNRZFaEDTNBGRNTg6YcAxZMiQzz//PLg+Kisrq6urJ0yY\nIP5xDN7UqVN//OMfDxgwICUlpeUZKEKIhISEgwcPrlixQgihKIrb7Z44caIQokePHitXrtQv\nLltXV5eRkSGEcLlcbrc7PT1d/wBlZ2frjcTHx2dkZJw/fz7QbJ8+ffr06RO4++qrr8bFxYVl\nFtFjTokTksfjURRFYgE+n8/v98fGxso9oM5ms8kaDfUjKq1Wq6w9M4/H43a7rVarrI+Bz+dz\nuVwS98z0PyZbLBZZBegBh9lslrtvajKZJBbgcrnkFhAYDGUFHIHBUNauoaIoPp/PZrOF5dfU\ntp+F2Wy22WwXvN1SjmkO/SPn9/v1103WJKKqqtfrlfjrvRBCn8WYRCROIna7nUlEsEfdgSaR\nIAT2qGVFjeHdo47YnGJSIhBGdMY1OJ599tnhw4f369evuLj4Sifgu++++yc/+Yl+++TJk//5\nn/+5bNmya665xm63NzU1eTwefbGMhoaG1atXT58+/dprr127dq0Q4ujRo6+99toTTzwh/rGn\nlZ2dnZqaWlFRMXLkSCFERUVFfHx8Tk6OECIhIeHo0aP6+qN2u/3cuXM9evS4ojoBAAAAAIhO\nETqCQ+2EV1F59NFHe/Xq9cADD/zqV7/q1avXBbnawYMH2/jeq666KrAsqH5yY48ePdLT07t2\n7Zqfn7906dKioiKbzfbGG2/U19f36NHDYrF07dpVCHHu3Dmr1arf1lksljFjxrzyyiuZmZlm\ns/mFF14YNWqUnrGNGTPmueeemzlzZkpKypYtWzIyMtpYywMAAAAAAAOJ0BocWic8gkM/E6Sw\nsDC83f/6179+8cUX169f73a78/LyHnzwwUselDVhwgSfz7dmzRpVVQsKCqZOnapvnzRpkslk\n2rRpk8PhyMvLmzdvnqzDqwAAAAAACC9NiIicoiLnKl4RcbkBx7vvvhuW/vr27fvf//3fgbsJ\nCQlz5sxp7cH9+/e/YIUOIYTJZJo8efLkyZO/vX3SpEmTJk0KS50AAAAAAEQRTagsMtomOetp\nAQAAAACAy6cJUyTWy+iMAcf3v//9Nr7a9hocAAAAAAAgRGoEwojOuAZH3759W971eDxHjx49\nfvz4LbfcMmjQoAgUBgAAAAAA/o+mReSKJ6qUK71HxuUGHDt37rxgi6Zpu3btmj59+lNPPRXu\nqgAAAAAAwL/QInFJ1w50ikrwK5SYTKaf/OQnU6ZMKSkpCWNBAAAAAADgQppJjcC/DnQRlRAC\nDl3fvn337dsXllIAAAAAAMBFaUKoqins/zrjIqMX5fP5tm/fnpSUFK5qAAAAAADARUXiMrGR\nWLhUlssNOEaPHn3BFlVVKysrT548OW/evHBXBQAAAAAA/knTInO0RScMOKqrq7+9sXv37pMm\nTVq0aFFYSwIAAAAAABeKxFVUtA60CMflBhwVFRURrQMAAAAAALRKEyISl3TthAGHTlXVr7/+\n+vjx436//9prr+3du7fFYolQZQAAAAAA4J84RaVNVxBw/OlPf/rVr3514MCBwJbvf//7q1ev\nHjFiRAQKAwAAAAAALUTgFJWOdATH5S7Bun///p/85Cfnz59fvHjx73//+x07dixZsqSmpmbM\nmDGfffZZREsEAAAAAKCz009RCfu/ywg4Pv74Y4vFctGlOS+ToiiLFi3q3bt3VlbWvHnzfD5f\n4Etbt269+eabk5OTR4wYceTIkaC7EJd/BMeiRYu6d+/+6aefZmRk6FvuuOOO4uLigQMHPv74\n47t27QqlCAAAAAAA0KaIXEXlkm3a7fZ7771XVUNa/6O0tHTdunUbN260Wq3FxcVms/npp58W\nQmzZsmXGjBlr1qz5zne+s3Tp0nHjxh06dCjopTAuN+D4/PPPp0+fHkg3dFdfffU999zz8ssv\nB9c3AAAAAAC4LJIWGZ0/f35CQkIoPXi93vXr15eWlo4fP14I4XQ6i4uLlyxZkpiYWFpaWlJS\nct999wkhsrOzp02bduzYsdzc3OA6utxTVLRWLh1jMnWc9UgAAAAAAIheqin8/9oMON5+++1d\nu3aVlZW13Oh0Oh988MHevXsnJyffdtttX375Zcuv2u32ysrKllsOHz589uzZ0aNH63dHjx7d\n1NT0+eefHzly5NChQ3feeae+PScnp7y8POh0Q1x+wJGfn//qq6+eP3++5cbz58+/9tprAwYM\nCLp7AAAAAABwWTRT+P+JVo9aOHfuXFFR0QsvvJCent5y+5QpU/7yl7+89NJLu3fvjo+Pv/XW\nW+vq6gJfraiomDhxYsvHV1VVCSGysrL0u2lpaUlJSdXV1WfOnBFCHDhwYODAgV26dCksLPzb\n3/4WystzuaeoLF26dMiQITfccMP999+fl5cnhDh48OD69evPnz+/ffv2UCoAAAAAAABti7PE\n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\n7713/Phxp9OpVqs/+OAD6TvAioqKXnrppezs7PDw8Mcffzw5ObmG7Vlp7NW9rbi4WOpLr9f3\n69cvNTV13rx5nmFXt9EqtZ+env6Pf/wjNzfX5XI1a9bs+eefd++Fus4CX46EGzkcjocffnjF\nihWe3+noOb+qG6Dvxo4du3jx4vj4+PHjx7/99ttt2rQRQly+fHnWrFkffvhhRETETY+Z2vdV\nf+efG4P0cbO498iaNWu8G2wlVR7bFoulys2+ePHiSp1WOa1qM1vd59Ibee7HxYsXS+Pt0KHD\n2LFjFyxYsGPHjrNnz7Zr127OnDk7d+48ePCgy+UaN27cgw8+KITwywFZ3SSqblxjx45dtmzZ\nzp07MzMzpe3Qv39/r49Gr5FGSaOkUdKoJ9JolUijAUijQrGZFHXFR1Rq8l//9V+PPPLI3//+\nd71eP3/+/JKSEpfLtXTp0kuXLs2bN+8vf/nL5cuXlyxZ4nK5qlvubuq3335btGjRpEmTvLss\nq6795OTkn3/+2WKxSG/77rvv7rnnnqCgoJUrV+bk5MyePXvp0qUhISELFiwwmUxeb4ROnTpJ\n5+7qmn355ZetVuvcuXMXLlyoUqneeecdIYTFYpk/f77T6Vy4cOGjjz76/vvvW63WWnbqcDj+\n9re/VVRULFq0aNy4catWrfJc1+uQli9f3qVLl8cee2zJkiU3jeHq1atpaWk9evR45ZVXRo4c\nuWHDhuzsbM8Wat7p7iD79++fnZ0tBbZw4cKQkBC73b5t2zbpbWvXrh0yZMjrr7+emJi4cuVK\nu91eXfA3jr3Ktzmdzr/97W8mk+nFF1987LHHvv32261bt1YaeA2Hh7t9afjFxcXx8fEjRoy4\nfv368uXLpb1Q11ngy5FQS5Xmlx+P/zq56TFTp9bq6fxTZZD+2gJeD7aSGqZAbTq9cVrVcrZ6\nN7T169dPnjxZ+mPpz3/+s06ne/XVV/v06bN+/fqSkhLhjwOyuklU87jWrFkzYMCA1157LT4+\nfsWKFTabzV87qPZIo4I0SholjdYaaZQ0Wk9pVCg5k6KuuIOjJlOnTu3fv78QokOHDjNmzNi3\nb1/Hjh3PnDnz/vvvt2jRQggxb968mTNnnjx5UqVSVbm8SZMmQogLFy68/PLLI0aMkMqQXsjO\nzq6y/bvvvvvtt9/++eef+/btW1BQkJ2dPX369EuXLqWnp2/cuFGqPs6dO3fatGm//PJLUlKS\nF1336NHj0UcfFUJU12zv3r3vv//+pKSkmJgYIURBQcHatWuFEPv377fZbAsWLDAYDEIIrVa7\nePHiWnZ65MiR/Pz8N998U1rXbDavXLnS95A0Go1KpVKr1Wr1zUt7V65ccTqdKSkpt99+e3x8\nfOvWrZs3b+7ZwsmTJ6vcKYmJiZ5BulyuyMjIy5cvv/baa3l5eYWFhdOnT79y5YrUy4gRI6Rj\nbOLEifv27SssLIyOjq4y+Epjd7lcVb7tp59+ys3NXbZsWXh4eOfOnR0OR05OjmfYNR8e7val\n/5LZbLYlS5bo9Xqj0Xjx4sX169eL6o/G6mbBxYsXvT4SaqPS/PLv8V8nNz1m6tRaPZ1/qgzS\nX1vA68F6qu7Yrn2nN06rvLy82szWWvZS6cF1o0eP7tKlixCib9++x48ff+yxx1Qq1YQJE/bu\n3Xv9+nWTyeT7AVnd6bS6ySiNq0+fPtK/3SZPnnzo0KH8/PzbbrvN9x1UJ6RRQRoljZJGa400\nShqtpzQqlJxJUVcUOGrStWtX6YeQkJBOnTpduHBBr9e3bNlSmgBCiBYtWrRo0eLChQsqlarK\n5dKZUbp/6fLly15HcuHChSrbT0xM7NWrV3p6et++ff/973/HxsZ26NDh3//+t9PpnDVrlnt1\ns9mcm5vrXdfSGUcIce7cuSqbValU999//8mTJ9PT03NycjIyMtwx33nnndJJRAghnSZq6Y8/\n/mjbtq173U6dOvklpDrp3LlzUlLSM888YzQau3fvPmjQIHc87gFWt1M8g1SpVLGxsb/99lt4\nePj27dsTExM9L9A7dOgg/aDVat3vryF4z2arfNu5c+dat24dHh4uvRwyZMiQIUM8W6huo1Vq\nv3PnzrGxsbm5uatWrZKGf/vtt0tXZtUNvLpZcPHiRa+PhNqoNL9qHmC9uukxUyf1dP7xb5D1\nwff5e+O0quVs9U7Lli2lH8LCwlq0aKFSqYQQ7jnolwOyutNpzeNybwd3MIFHGhWkUdIoabTW\nSKN+QRqtknIzKeqKAkdtqdVq6dOelahUKqfTqdFoqlwu/Txu3Lg8nND2AAAPzUlEQVR27dq9\n+OKLKSkp3bt390s87vaTk5PXrFnjcDgOHz48ePBgaXlERMSKFSs83+/1yTcsLEz6obpmLRbL\nggULKioq7rnnngceeKBPnz7vvvuuEKLSNlGpVNIJqzYcDofnmyuVSL0OqU60Wu2LL754+fLl\nQ4cO7d+/f9OmTXPmzKm5Wuy5091BCiFat26dnZ1dXFx88ODBShVud+Zwqzl4d7PVvc3hcNx4\nNHqq+fBwt6/Vavv37//TTz+1b99eGv60adNqHnh1s8CXI6E2Ks0v/x7/tWGz2aQfvDhmasmP\n55/6C9Jfajl/3Zv9RjdOqxtVN1u94Hk833hs++WArP0k8hxXSEhInXqpb6RR0ihptOaBk0ZJ\no35BGq1S48ikqA1uramJ+1ugrVZrdnZ2mzZtWrVqde3atby8PGn5tWvXrl69escdd1S3XHo5\ndOjQbt26DRgw4L333quoqPAikhra7927t91uP3DgwC+//DJw4EAhROvWrUtKSqxWq1SD1Gq1\nq1evzs/P92FLiBqazcrKunDhwooVKx555JGEhAT3GaF169anT58uLy+XXp44ccLz04w37ev3\n3393r/vLL7/4JaQ6yczM3LRpU0xMzPjx419//fUePXp8/fXXnm+oead7ki7H33//fZPJ1K9f\nvy+++GL27NnV9VvL4GvY7H/88Yf7O9tv7KuWh0dmZua5c+cuXbo0cuRIafhffvllzQOvbrkv\nR0JtVJpf9XT836i0tFT64cyZM9IPNz1m6qSezj/+DbI+1DwFbtzstVH72ep3fjkgq5tEMo6r\nlkijnkijpNGaB04aJY36BWm0unYUmklRVxQ4qhUUFLR+/frDhw+fPHnytddeE0IMHjy4S5cu\n7du3T0tLy8rKysrKSktLa9++fWJiYnXLPRt84oknrl+//tlnn3kRTA3t63S63r17r1u3LjEx\nMTo6WggRFxfXs2fPpUuXHj16NCMjY/ny5Xl5ea1atfJxg1TXrMFgsFqt+/fvLygo+P777z/8\n8EOr1Zqfn3/PPfdotdpXXnnlxIkT33///X//9397Pqy7Zn379o2IiHjjjTdOnTp15MiR7du3\nixv+AeVFSEIIlUp1+fLlwsLCm8agVqu3b9++Y8eO33777eDBg6dOnZKev+1uoTY7XdKnT5+w\nsLCDBw8mJCT88MMPW7ZsqeH+0hqCr83b7r777mbNmi1fvvzUqVMHDhxw9+UOu5aHh1qtPnr0\nqEajeemll7Zs2ZKZmXn9+nVpeV1ngS9HQu2551c9Hf+eQkJCIiIitm7dmpOT8+OPP+7evVta\nftNjpvZd1N/5p7og/cWLwVZS3bFd3WavTae1n61+H5pfDsjqJpEX4/J9B9UeabQS0ihpVJBG\nhRCk0RqRRivx1wGp0EwKL2j8+5iiRqOgoODo0aP/+Z//uWXLls8//zwqKuqFF15o2rSpSqXq\n06fP6dOnd+zYcfjw4fj4+Dlz5uh0uuqWl5SU7Nmz55FHHtFqtXq9Pjg4ePPmzffee2/tb6za\nvHnzfffd16JFiyrbl96jUqm++eabSZMmtW3bVlqSlJSUm5v76aef7t+/v1WrVs8//7x3nxzb\nsmXL4MGD3R+Nq7LZ6OholUq1ffv2zz//3Gw2P/PMMxkZGenp6SNGjLj77ruPHTu2c+fOs2fP\nTp069ezZs0ajUXriUc00Gk1SUtIPP/ywffv2K1euTJ069dtvv500aZJOp/MlpJSUFJVKtWvX\nrnPnzt1zzz01x9CiRYuwsLA9e/Z8+umnp06dGjhw4MSJE9VqtWcL1e2USkGq1erY2NhDhw4V\nFxdnZWX1798/NTU1KCho69atgwYNkt5msVj+9a9/jR49Oi4urrrgPZutbozDhw/v06dPRkbG\ntm3bMjMz3X15hl3d4eHZvjT8nJycCxcuZGVlhYWFPfvss/v375f2Qp1mQVBQkNdHQiXSdGje\nvPknn3ySkpISFBRU5fwaNGiQX47/G7l3WVxc3KFDh3bv3n3t2rWnnnrqiy++GDNmTOvWrW96\nzNSml3o9/0yYMKFFixY3BunLZnG5XNIekYKs02BvVMP8rXKzh4SEeHZa5bQKCwur5WytgbuX\n5ORk93i3bt06cOBA6WDOzMwsKCgYNGiQEKKiomLbtm3Dhw+Piory/YRcwySqblyegVmt1h07\ndowaNSo8PNz3HVRLpFEJaZQ0Shr1RBqtEmm0vtOoUGYmhXdU/r3JDfCLvLy8o0ePDh8+XPq8\nXFZW1qJFi7Zv367c5xV//fXXmzZt2rBhQ82f7G1QGt9e8N2YMWOWLFnifm4ZADRMje8EThpt\nHEijAOobDxlFQ6TVajdu3Jibmztq1CiLxbJhw4bBgwcr9IKgrKzs119/3b59u/sSRyka017w\nXUVFRVZWVkVFBY+bAtDwNaYTOGm0cSCNAggM7uBAA5WVlbVx48Zz5841adKkd+/eqamper1e\n7qC8cf78+RdeeKFr165z586t8gneDVmj2Qu+y8zMfOmll5KSkp5//nllXWEDuDU1mhM4abRx\nII0CCAwKHAAAAAAAQPFu0dvkAAAAAABAY0KBAwAAAAAAKB4FDgAAAAAAoHgUOAAAAAAAgOJR\n4AAAAAAAAIpHgQMAAAAAACgeBQ4AABqJN954Q6VSXb9+vU5r9erVa9CgQfUTkZJiAAAASkeB\nAwCAW5per9fr9cQAAACULkjuAAAAgJwOHTokdwgNIgYAAKB03MEBAAAAAAAUjwIHAAD1aODA\ngdHR0U6nU3o5f/58lUr19NNPu98QFxeXmJgo/Xzs2LERI0a0bNkyJibm/vvv//HHH91vu+++\n+x555JEzZ84MHz48Li5OWrhly5Z+/fpFREQYjcZ33nnHs9/i4uK5c+e2b99ep9O1bdv2ueee\nKykpqTLC5ORk9/Mvhg8f/tBDD506dWro0KGhoaExMTEzZswoLi6ucsUqQ/rjjz8mT54cFxcX\nHh6enJy8c+dOafmjjz6q0Wg8nw9iNpvDw8NTUlIqxVBDI7XfmLUfPgAAaDQocAAAUI9SUlKu\nX7+enZ0tvZQ+i3Hw4EHp5fnz58+fPz98+HAhxNdff923b98TJ05MmzZt6tSpJ06c6Nu37969\ne91NFRUVjRo16uLFi9L7V6xYMWnSpOvXrz/55JNJSUl//etfV69e7X7zxIkT33rrre7duy9Y\nsKBLly4rV6588sknaxPw5cuX77333vj4+JUrVw4cOHDdunVz5syp7s2VQjp16tRdd9118ODB\niRMnPv/880VFRWPGjHn77beFEOPHj3c6nbt27XKv++WXX5aWlj7++OOV2qyhkdpvTK+HDwAA\nFMwFAADqjXQXxttvv+1yucxms1arTUhIUKlUBQUFLpdr48aNQoivvvrK4XAkJibedtttV69e\nlVa8evVqTExM165dHQ6Hy+UaMmSIEGLWrFlOp9PlcuXl5YWHh3fv3r2kpER6/5EjR1QqlRAi\nLy8vPz9fCPHMM8+4w5g8eXJ8fLy0biX9+/cfOHCg9LN0P8WqVaukl06nMykpqXXr1lUOrVJI\nLpdr1KhRbdq0kYbmcrlsNtvAgQP1en1hYaF0v8aoUaPcq0+cODE8PLysrKxSDDU0UsuNWafh\nAwCARoM7OAAAqEc9evRo3rz5t99+K4T44YcfbDbbggULXC7Xd999J4Q4ePCgwWBITk4+d+7c\niRMn/uM//qNFixbSii1atPjzn/+clZV1/vx5aYlKpXrzzTelKsb+/ftNJtOCBQvCw8Ol3959\n993333+/9HNISIhGo9m/f39OTo605KOPPjp9+rS0bs20Wu2sWbPcPXbv3r28vLy6N3uGVFZW\ntmvXrscee0ylUhUVFRUVFZWVlT3++ONmszk9PV2n0z300EN79+4tLS0VQpSXl+/atWvcuHEG\ng8GzwZobqeXG9GX4AABAuShwAABQj9RqdUpKyoEDB5xO56FDh6KjoydMmBAeHn7gwAEhxIED\nB+69916dTif9Kd61a1fPdaWXZ8+elV7GxcWFhoZKP585c0YI0aNHD8/3d+vWTfohNDR09erV\np0+fjo+PNxqNs2fP/uabb1wuV20CvuOOO0JCQjzjr+HNN4a0bNmyKA/Tp08XQuTl5Qkhxo8f\nb7Vav/zySyHEF198UVZWlpqaWqnBmhup5cb0ZfgAAEC5+JpYAADqV0pKykcffXTy5Mnvvvsu\nOTk5KChowIABBw8ezM3NzcnJefbZZ4UQVf75LRUXKioqpJdNmzZ1/yooqIoM7lmMmDVr1sMP\nP7x79+59+/Zt3rx51apVw4YN2717d3BwcM3RelY3bsozJCnOF154Qfqci6eOHTsKIYYNGxYZ\nGblz585HHnlk69atbdq0GTBgQKV33rSR2mxMX4YPAACUizs4AACoX8OGDRNC7Nu37/Dhw8nJ\nyUKIgQMH/vTTT3v27BFCSA/FbN++vRDixIkTnitmZWUJIeLj429sU3r/zz//7LkwMzNT+iE/\nP//HH38MCQmZPn36Rx99dPHixblz5+7du/fzzz+vh/H9DynOoKCgQR5iYmIuXrwofY5Gq9U+\n/PDDe/bsKSoq2r17d2pq6o23h9y0kdpsTFmGDwAAZEeBAwCA+tWyZcu77rprzZo1JSUl7r/J\nHQ7H66+/3r59+w4dOggh2rZtm5CQsGbNGunTHEKIa9eurVmzJiEhwf0NrJ4GDRoUGRm5bNky\n97efHj16VPojXwhx8uTJ3r17r1ixQnoZHBx89913CyHq9SEUkZGRAwcOfPfdd3/99VdpidVq\nTU1N/etf/+p+0Mb48eOlL3AtLy+fMmWKF43UZmPKMnwAACA7PqICAEC9S0lJSUtL0+v10lMz\nevbsGRoampOT4/7uUo1Gs2LFipEjR/bq1Wvy5Mkul+ujjz66fv36pk2bNBrNjQ02bdp0yZIl\ns2fP7tWr19ixY0tKSjZu3Ch9WEMI0bt3744dOy5btuzcuXOdO3fOzMzcvXt3u3btBg0aVK/D\nXLFixYABA/r37z9hwoTY2Nht27ZlZGRs2bLFPYT77rsvKipq7dq1/fr1q/LOlNo0ctONKdfw\nAQCAvLiDAwCAeid9dKJPnz7SMyCCg4Oluw+k5ZKUlJTDhw936tRp/fr1GzZsSExMTE9PHzp0\naHVtPvvss5988kl0dPTq1avT09NfeeWV+fPnS7/S6/VffPHF+PHj9+3bt2jRovT09AkTJnz7\n7bcRERH1OsyePXv+/PPPAwYM+PTTT9PS0sLCwj7//PMJEya43xAcHDxmzBghxI2PF619Izfd\nmHINHwAAyEvFQ8UBAAAAAIDScQcHAAAAAABQPAocAAAAAABA8ShwAAAAAAAAxaPAAQAAAAAA\nFI8CBwAAAAAAUDwKHAAAAAAAQPEocAAAAAAAAMWjwAEAAAAAABTv/wGcuk1JNNb/CwAAAABJ\nRU5ErkJggg==", "text/plain": [ "plot without title" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "g + \n", " geom_col(aes(y=n, fill = n)) + \n", " scale_fill_viridis() +\n", " facet_grid(. ~ label)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Using **bokeh**:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": true }, "outputs": [], "source": [ "p1 <- positive_reviews %>% \n", " figure() %>% \n", " ly_bar(x = word2, y = n,\n", " hover = TRUE, color = NULL) %>%\n", " x_axis(label = \"positive words\") %>%\n", " y_axis(label = \"count\") " ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": true, "scrolled": true }, "outputs": [], "source": [ "p2 <- negative_reviews %>% \n", " figure() %>% \n", " ly_bar(x = word2, y = n,\n", " hover = TRUE) %>%\n", " x_axis(label = \"negative words\") %>%\n", " y_axis(label = \"count\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Printing **bokeh** plots:" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false, "scrolled": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", " \n", "\n", "\n", "\n", "\n", "
\n", "
\n", "\n", "
\n", "
\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "HTML widgets cannot be represented in plain text (need html)" ] }, "metadata": { "text/html": { "isolated": true } }, "output_type": "display_data" } ], "source": [ "grid_plot(list(p2, p1), same_axes = TRUE, width=900, height=350)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Split Data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Split data into training and evaluation data for our model:" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "collapsed": true }, "outputs": [], "source": [ "partitions <- unnested_reviews %>%\n", " sdf_partition(trainingData = 0.8, testData = 0.2)" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\t\n", "\t\n", "\t\n", "\n", "
labelwordn
0 \"and 600
0 \"book\"737
0 \"for 619
\n" ], "text/latex": [ "\\begin{tabular}{r|lll}\n", " label & word & n\\\\\n", "\\hline\n", "\t 0 & \"and & 600 \\\\\n", "\t 0 & \"book\" & 737 \\\\\n", "\t 0 & \"for & 619 \\\\\n", "\\end{tabular}\n" ], "text/markdown": [ "\n", "label | word | n | \n", "|---|---|---|\n", "| 0 | \"and | 600 | \n", "| 0 | \"book\" | 737 | \n", "| 0 | \"for | 619 | \n", "\n", "\n" ], "text/plain": [ " label word n \n", "1 0 \"and 600\n", "2 0 \"book\" 737\n", "3 0 \"for 619" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "partitions$trainingData %>% \n", " head(3) %>%\n", " collect" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\t\n", "\t\n", "\t\n", "\n", "
labelwordn
0 \"all 644
0 \"he 970
0 \"if 1209
\n" ], "text/latex": [ "\\begin{tabular}{r|lll}\n", " label & word & n\\\\\n", "\\hline\n", "\t 0 & \"all & 644\\\\\n", "\t 0 & \"he & 970\\\\\n", "\t 0 & \"if & 1209\\\\\n", "\\end{tabular}\n" ], "text/markdown": [ "\n", "label | word | n | \n", "|---|---|---|\n", "| 0 | \"all | 644 | \n", "| 0 | \"he | 970 | \n", "| 0 | \"if | 1209 | \n", "\n", "\n" ], "text/plain": [ " label word n \n", "1 0 \"all 644\n", "2 0 \"he 970\n", "3 0 \"if 1209" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "partitions$testData %>%\n", " head(3) %>%\n", " collect()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Session " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Paths recognised by R " ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": true }, "outputs": [], "source": [ ".libPaths()\n", "Sys.getenv(\"R_HOME\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### R session info" ] }, { "cell_type": "code", "execution_count": 202, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "R version 3.3.2 (2016-10-31)\n", "Platform: x86_64-pc-linux-gnu (64-bit)\n", "Running under: CentOS Linux 7 (Core)\n", "\n", "locale:\n", " [1] LC_CTYPE=es_ES.UTF-8 LC_NUMERIC=C \n", " [3] LC_TIME=es_ES.UTF-8 LC_COLLATE=es_ES.UTF-8 \n", " [5] LC_MONETARY=es_ES.UTF-8 LC_MESSAGES=es_ES.UTF-8 \n", " [7] LC_PAPER=es_ES.UTF-8 LC_NAME=C \n", " [9] LC_ADDRESS=C LC_TELEPHONE=C \n", "[11] LC_MEASUREMENT=es_ES.UTF-8 LC_IDENTIFICATION=C \n", "\n", "attached base packages:\n", "[1] stats graphics grDevices utils datasets methods base \n", "\n", "other attached packages:\n", " [1] gridExtra_2.2.1 viridis_0.4.0 viridisLite_0.2.0 bindrcpp_0.2 \n", " [5] rbokeh_0.5.0 purrr_0.2.2.2 tidyr_0.6.0 tidytext_0.1.3 \n", " [9] repr_0.10 ggplot2_2.2.1 knitr_1.15.1 dplyr_0.7.1 \n", "[13] sparklyr_0.5.6 SparkR_1.6.1 \n", "\n", "loaded via a namespace (and not attached):\n", " [1] Rcpp_0.12.8 lattice_0.20-34 assertthat_0.1 rprojroot_1.1 \n", " [5] digest_0.6.10 psych_1.6.9 mime_0.5 IRdisplay_0.4.4 \n", " [9] R6_2.2.0 plyr_1.8.4 backports_1.0.4 evaluate_0.10 \n", "[13] httr_1.2.1 rlang_0.1.1 lazyeval_0.2.0 uuid_0.1-2 \n", "[17] rstudioapi_0.6 hexbin_1.27.1 Matrix_1.2-7.1 rmarkdown_1.6 \n", "[21] labeling_0.3 config_0.2 stringr_1.2.0 foreign_0.8-67 \n", "[25] htmlwidgets_0.8 munsell_0.4.3 shiny_1.0.3 broom_0.4.1 \n", "[29] janeaustenr_0.1.5 httpuv_1.3.3 gistr_0.3.6 pkgconfig_2.0.1 \n", "[33] base64enc_0.1-3 mnormt_1.5-5 htmltools_0.3.5 tibble_1.3.3 \n", "[37] codetools_0.2-15 withr_1.0.2 crayon_1.3.2 dbplyr_1.1.0 \n", "[41] SnowballC_0.5.1 grid_3.3.2 nlme_3.1-128 jsonlite_1.1 \n", "[45] xtable_1.8-2 gtable_0.2.0 DBI_0.7 magrittr_1.5 \n", "[49] scales_0.4.1 tokenizers_0.1.4 stringi_1.1.2 pryr_0.1.2 \n", "[53] reshape2_1.4.2 IRkernel_0.7.1 RColorBrewer_1.1-2 tools_3.3.2 \n", "[57] glue_1.1.1 maps_3.1.1 yaml_2.1.14 parallel_3.3.2 \n", "[61] colorspace_1.3-1 pbdZMQ_0.2-4 bindr_0.1 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "sessionInfo()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## References \n", "\n", "- [`sparklyr` presentation](https://cdn.oreillystatic.com/en/assets/1/event/193/Sparklyr_%20An%20R%20interface%20for%20Apache%20Spark%20Presentation.pdf)\n", "- [`sparklyr` tutorial](http://spark.rstudio.com/).\n", "- [`sparklyr` cheatsheet](http://spark.rstudio.com/images/sparklyr-cheatsheet.pdf).\n", "- [`sparklyr`: creating extensions](http://spark.rstudio.com/extensions.html).\n", "- [Differences between `sparkr` and `sparklyr`](https://stackoverflow.com/questions/39494484/sparkr-vs-sparklyr).\n", "- [Hive Operators and UDFs](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF).\n", "- [String Functions in Hive](http://www.folkstalk.com/2011/11/string-functions-in-hive.html).\n", "- [POSIX regular expressions](https://www.postgresql.org/docs/9.4/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP).\n", "- [Material for Machine Learning Workshop Galicia 2016](http://nbviewer.jupyter.org/github/javicacheiro/machine_learning_galicia_2016/blob/master/notebooks/sentiment_analysis-amazon_books.ipynb).\n", "- [PySpark Course](https://github.com/javicacheiro/pyspark_course)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "R", "language": "R", "name": "ir" }, "language_info": { "codemirror_mode": "r", "file_extension": ".r", "mimetype": "text/x-r-source", "name": "R", "pygments_lexer": "r", "version": "3.3.3" } }, "nbformat": 4, "nbformat_minor": 1 }