├── LICENSE ├── README.md ├── Rstart.R ├── reddit-bigquery-1.png ├── reddit-bigquery-2.png ├── reddit-bigquery-3.png ├── reddit_bigquery.ipynb ├── subreddit-ranks.gif └── subreddit-ranks ├── 2010-08-01.png ├── 2010-09-01.png ├── 2010-10-01.png ├── 2010-11-01.png ├── 2010-12-01.png ├── 2011-01-01.png ├── 2011-02-01.png ├── 2011-03-01.png ├── 2011-04-01.png ├── 2011-05-01.png ├── 2011-06-01.png ├── 2011-07-01.png ├── 2011-08-01.png ├── 2011-09-01.png ├── 2011-10-01.png ├── 2011-11-01.png ├── 2011-12-01.png ├── 2012-01-01.png ├── 2012-02-01.png ├── 2012-03-01.png ├── 2012-04-01.png ├── 2012-05-01.png ├── 2012-06-01.png ├── 2012-07-01.png ├── 2012-08-01.png ├── 2012-09-01.png ├── 2012-10-01.png ├── 2012-11-01.png ├── 2012-12-01.png ├── 2013-01-01.png ├── 2013-02-01.png ├── 2013-03-01.png ├── 2013-04-01.png ├── 2013-05-01.png ├── 2013-06-01.png ├── 2013-07-01.png ├── 2013-08-01.png ├── 2013-09-01.png ├── 2013-10-01.png ├── 2013-11-01.png ├── 2013-12-01.png ├── 2014-01-01.png ├── 2014-02-01.png ├── 2014-03-01.png ├── 2014-04-01.png ├── 2014-05-01.png ├── 2014-06-01.png ├── 2014-07-01.png ├── 2014-08-01.png ├── 2014-09-01.png ├── 2014-10-01.png ├── 2014-11-01.png ├── 2014-12-01.png ├── 2015-01-01.png ├── 2015-02-01.png ├── 2015-03-01.png ├── 2015-04-01.png ├── 2015-05-01.png ├── 2015-06-01.png ├── 2015-07-01.png └── 2015-08-01.png /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Max Woolf 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reddit Data with BigQuery 2 | Code + Jupyter notebook for analyzing and visualizing Reddit Data quickly and easily. This notebook is the complement for my blog post [How to Analyze Every Reddit Submission and Comment, in Seconds, for Free](http://minimaxir.com/2015/10/reddit-bigquery/). 3 | -------------------------------------------------------------------------------- /Rstart.R: -------------------------------------------------------------------------------- 1 | library(readr) 2 | library(dplyr) 3 | library(ggplot2) 4 | library(extrafont) 5 | library(scales) 6 | library(grid) 7 | library(RColorBrewer) 8 | library(digest) 9 | library(readr) 10 | library(stringr) 11 | 12 | 13 | fontFamily <- "Source Sans Pro" 14 | fontTitle <- "Source Sans Pro Semibold" 15 | 16 | color_palette = c("#16a085","#27ae60","#2980b9","#8e44ad","#f39c12","#c0392b","#1abc9c", "#2ecc71", "#3498db", "#9b59b6", "#f1c40f","#e74c3c") 17 | 18 | neutral_colors = function(number) { 19 | return (brewer.pal(11, "RdYlBu")[-c(5:7)][(number %% 8) + 1]) 20 | } 21 | 22 | set1_colors = function(number) { 23 | return (brewer.pal(9, "Set1")[c(-6,-8)][(number %% 7) + 1]) 24 | } 25 | 26 | theme_custom <- function() {theme_bw(base_size = 8) + 27 | theme(panel.background = element_rect(fill="#eaeaea"), 28 | plot.background = element_rect(fill="white"), 29 | panel.grid.minor = element_blank(), 30 | panel.grid.major = element_line(color="#dddddd"), 31 | axis.ticks.x = element_blank(), 32 | axis.ticks.y = element_blank(), 33 | axis.title.x = element_text(family=fontTitle, size=8, vjust=-.3), 34 | axis.title.y = element_text(family=fontTitle, size=8, vjust=1.5), 35 | panel.border = element_rect(color="#cccccc"), 36 | text = element_text(color = "#1a1a1a", family=fontFamily), 37 | plot.margin = unit(c(0.25,0.1,0.30,0.35), "cm"), 38 | plot.title = element_text(family=fontTitle, size=9, vjust=1)) 39 | } 40 | 41 | create_watermark <- function(source = '', filename = '', dark=F) { 42 | 43 | symbols <- c('','', '', '') 44 | symbol <- symbols[strtoi(substr(digest(filename),1,6), base=36) %% length(symbols)] 45 | if (length(symbol)==0) symbol <- symbols[1] 46 | 47 | bg_white = "#F0F0F0" 48 | bg_text = '#969696' 49 | 50 | if (dark) { 51 | bg_white = "#000000" 52 | bg_text = '#666666' 53 | } 54 | 55 | watermark <- ggplot(aes(x,y), data=data.frame(x=c(0.5), y=c(0.5))) + geom_point(color = "transparent") + 56 | geom_text(x=0, y=0.9, label="By Max Woolf — minimaxir.com", family="Source Sans Pro", color=bg_text, size=1.75, hjust=0) + 57 | 58 | geom_text(x=5, y=0.9, label="Made using R and ggplot2", family="Source Sans Pro", color=bg_text, size=1.75) + 59 | #geom_text(x=0, y=1.01, label = symbol, family = 'FontAwesome', color=bg_text, size=2) + 60 | #geom_text(x=8, y=1, label = "via FiveThirtyEight", family="M+ 1m light", color="white") + 61 | scale_x_continuous(limits=c(0,10)) + 62 | scale_y_continuous(limits=c(0.5,1.5)) + 63 | annotate("segment", x = 0, xend = 10, y=1.5, yend=1.5, color=bg_text, size=0.1) + 64 | theme_bw() + 65 | theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), legend.position = "none", 66 | panel.border = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank(), axis.title.x = element_blank(), axis.title.y = element_blank(), 67 | axis.ticks = element_blank(), plot.margin = unit(c(0.1,0,-0.4,0), "cm")) + 68 | theme(plot.background=element_rect(fill=bg_white, color=bg_white),panel.background=element_rect(fill=bg_white, color=bg_white)) + 69 | scale_color_manual(values=bg_text) 70 | 71 | if (nchar(source) > 0) {watermark <- watermark + geom_text(x=10, y=0.9, label=paste("Data via",source), family="Source Sans Pro", color=bg_text, size=1.75, hjust=1)} 72 | 73 | return (watermark) 74 | } 75 | 76 | web_Layout <- grid.layout(nrow = 2, ncol = 1, heights = unit(c(2, 77 | 0.125), c("null", "null")), ) 78 | tallweb_Layout <- grid.layout(nrow = 2, ncol = 1, heights = unit(c(3.5, 79 | 0.125), c("null", "null")), ) 80 | video_Layout <- grid.layout(nrow = 1, ncol = 2, widths = unit(c(2, 81 | 1), c("null", "null")), ) 82 | 83 | #grid.show.layout(Layout) 84 | vplayout <- function(...) { 85 | grid.newpage() 86 | pushViewport(viewport(layout = web_Layout)) 87 | } 88 | 89 | talllayout <- function(...) { 90 | grid.newpage() 91 | pushViewport(viewport(layout = tallweb_Layout)) 92 | } 93 | 94 | vidlayout <- function(...) { 95 | grid.newpage() 96 | pushViewport(viewport(layout = video_Layout)) 97 | } 98 | 99 | subplot <- function(x, y) viewport(layout.pos.row = x, 100 | layout.pos.col = y) 101 | 102 | web_plot <- function(a, b) { 103 | vplayout() 104 | print(a, vp = subplot(1, 1)) 105 | print(b, vp = subplot(2, 1)) 106 | } 107 | 108 | tallweb_plot <- function(a, b) { 109 | talllayout() 110 | print(a, vp = subplot(1, 1)) 111 | print(b, vp = subplot(2, 1)) 112 | } 113 | 114 | video_plot <- function(a, b) { 115 | vidlayout() 116 | print(a, vp = subplot(1, 1)) 117 | print(b, vp = subplot(1, 2)) 118 | } 119 | 120 | max_save <- function(plot1, filename, source = '', pdf = FALSE, w=4, h=3, tall=F, dark=F) { 121 | png(paste(filename,"png",sep="."),res=300,units="in",width=w,height=h) 122 | ifelse(tall,tallweb_plot(plot1,create_watermark(source, filename, dark)),web_plot(plot1,create_watermark(source, filename, dark))) 123 | dev.off() 124 | 125 | if (pdf) { 126 | quartz(width=w,height=h,dpi=144) 127 | web_plot(plot1,create_watermark(source, filename, dark)) 128 | quartz.save(paste(filename,"pdf",sep="."), type = "pdf", device = dev.cur()) 129 | } 130 | } 131 | 132 | video_save <- function(plot1, plot2, filename) { 133 | png(paste(filename,"png",sep="."),res=300,units="in",width=1920/300,height=1080/300) 134 | video_plot(plot1,plot2) 135 | dev.off() 136 | 137 | } 138 | 139 | fte_theme <- function (palate_color = "Greys") { 140 | 141 | #display.brewer.all(n=9,type="seq",exact.n=TRUE) 142 | palate <- brewer.pal(palate_color, n=9) 143 | color.background = palate[2] 144 | color.grid.minor = palate[3] 145 | color.grid.major = palate[3] 146 | color.axis.text = palate[6] 147 | color.axis.title = palate[7] 148 | color.title = palate[9] 149 | #color.title = "#2c3e50" 150 | 151 | font.title <- "Source Sans Pro" 152 | font.axis <- "Open Sans Condensed Bold" 153 | #font.axis <- "M+ 1m regular" 154 | #font.title <- "Arial" 155 | #font.axis <- "Arial" 156 | 157 | 158 | theme_bw(base_size=9) + 159 | # Set the entire chart region to a light gray color 160 | theme(panel.background=element_rect(fill=color.background, color=color.background)) + 161 | theme(plot.background=element_rect(fill=color.background, color=color.background)) + 162 | theme(panel.border=element_rect(color=color.background)) + 163 | # Format the grid 164 | theme(panel.grid.major=element_line(color=color.grid.major,size=.25)) + 165 | theme(panel.grid.minor=element_blank()) + 166 | #scale_x_continuous(minor_breaks=0,breaks=seq(0,100,10),limits=c(0,100)) + 167 | #scale_y_continuous(minor_breaks=0,breaks=seq(0,26,4),limits=c(0,25)) + 168 | theme(axis.ticks=element_blank()) + 169 | # Dispose of the legend 170 | theme(legend.position="none") + 171 | theme(legend.background = element_rect(fill=color.background)) + 172 | theme(legend.text = element_text(size=7,colour=color.axis.title,family=font.axis)) + 173 | # Set title and axis labels, and format these and tick marks 174 | theme(plot.title=element_text(colour=color.title,family=font.title, size=9, vjust=1.25, lineheight=0.1)) + 175 | theme(axis.text.x=element_text(size=7,colour=color.axis.text,family=font.axis)) + 176 | theme(axis.text.y=element_text(size=7,colour=color.axis.text,family=font.axis)) + 177 | theme(axis.title.y=element_text(size=7,colour=color.axis.title,family=font.title, vjust=1.25)) + 178 | theme(axis.title.x=element_text(size=7,colour=color.axis.title,family=font.title, vjust=0)) + 179 | 180 | # Big bold line at y=0 181 | #geom_hline(yintercept=0,size=0.75,colour=palate[9]) + 182 | # Plot margins and finally line annotations 183 | theme(plot.margin = unit(c(0.35, 0.2, 0.15, 0.4), "cm")) + 184 | 185 | theme(strip.background = element_rect(fill=color.background, color=color.background),strip.text=element_text(size=7,colour=color.axis.title,family=font.title)) 186 | 187 | } 188 | -------------------------------------------------------------------------------- /reddit-bigquery-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/reddit-bigquery-1.png -------------------------------------------------------------------------------- /reddit-bigquery-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/reddit-bigquery-2.png -------------------------------------------------------------------------------- /reddit-bigquery-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/reddit-bigquery-3.png -------------------------------------------------------------------------------- /reddit_bigquery.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Reddit Data with BigQuery\n", 8 | "\n", 9 | "by [Max Woolf](http://minimaxir.com)\n", 10 | "\n", 11 | "This notebook is the complement for my blog post [How to Analyze Every Reddit Submission and Comment, in Seconds, for Free](http://minimaxir.com/2015/10/reddit-bigquery/)." 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": 38, 17 | "metadata": { 18 | "collapsed": false 19 | }, 20 | "outputs": [], 21 | "source": [ 22 | "options(warn=-1)\n", 23 | "\n", 24 | "# IMPORTANT: This assumes that all packages in \"Rstart.R\" are installed,\n", 25 | "# and the fonts \"Source Sans Pro\" and \"Open Sans Condensed Bold\" are installed\n", 26 | "# via extrafont. If ggplot2 charts fail to render, you may need to change/remove the theme call.\n", 27 | "\n", 28 | "source(\"Rstart.R\")\n", 29 | "library(tidyr)\n", 30 | "library(bigrquery)\n", 31 | "library(methods) # needed for query_exec in Jupyter: https://github.com/hadley/bigrquery/issues/32\n", 32 | "library(wordcloud)\n", 33 | "library(digest)\n", 34 | "\n", 35 | "options(repr.plot.mimetypes = 'image/png', repr.plot.width=4, repr.plot.height=3, repr.plot.res=300)" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "## rbigquery\n", 43 | "\n", 44 | "This uses the `rbigquery` R package to query the data. Ensure that it is set up correctly, with your own project name from BigQuery." 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 4, 50 | "metadata": { 51 | "collapsed": true 52 | }, 53 | "outputs": [], 54 | "source": [ 55 | "project_name <- # DO NOT SHARE!" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "## Hello World!\n", 63 | "\n", 64 | "Simple query to test things out." 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 10, 70 | "metadata": { 71 | "collapsed": false 72 | }, 73 | "outputs": [ 74 | { 75 | "data": { 76 | "text/html": [ 77 | "\n", 78 | "\n", 79 | "\n", 80 | "\t\n", 81 | "\t\n", 82 | "\t\n", 83 | "\t\n", 84 | "\t\n", 85 | "\t\n", 86 | "\t\n", 87 | "\t\n", 88 | "\t\n", 89 | "\t\n", 90 | "\n", 91 | "
date_submissionnum_submissions
12015-08-23170999
22015-08-24163107
32015-08-25264787
42015-08-26235858
52015-08-27212472
62015-08-28206100
72015-08-29180039
82015-08-30183686
92015-08-31214685
102015-09-0110299
\n" 92 | ], 93 | "text/latex": [ 94 | "\\begin{tabular}{r|ll}\n", 95 | " & date_submission & num_submissions\\\\\n", 96 | "\\hline\n", 97 | "\t1 & 2015-08-23 & 170999\\\\\n", 98 | "\t2 & 2015-08-24 & 163107\\\\\n", 99 | "\t3 & 2015-08-25 & 264787\\\\\n", 100 | "\t4 & 2015-08-26 & 235858\\\\\n", 101 | "\t5 & 2015-08-27 & 212472\\\\\n", 102 | "\t6 & 2015-08-28 & 206100\\\\\n", 103 | "\t7 & 2015-08-29 & 180039\\\\\n", 104 | "\t8 & 2015-08-30 & 183686\\\\\n", 105 | "\t9 & 2015-08-31 & 214685\\\\\n", 106 | "\t10 & 2015-09-01 & 10299\\\\\n", 107 | "\\end{tabular}\n" 108 | ], 109 | "text/plain": [ 110 | "Source: local data frame [10 x 2]\n", 111 | "\n", 112 | " date_submission num_submissions\n", 113 | " (chr) (int)\n", 114 | "1 2015-08-23 170999\n", 115 | "2 2015-08-24 163107\n", 116 | "3 2015-08-25 264787\n", 117 | "4 2015-08-26 235858\n", 118 | "5 2015-08-27 212472\n", 119 | "6 2015-08-28 206100\n", 120 | "7 2015-08-29 180039\n", 121 | "8 2015-08-30 183686\n", 122 | "9 2015-08-31 214685\n", 123 | "10 2015-09-01 10299" 124 | ] 125 | }, 126 | "execution_count": 10, 127 | "metadata": {}, 128 | "output_type": "execute_result" 129 | } 130 | ], 131 | "source": [ 132 | "sql <- \"SELECT DATE(SEC_TO_TIMESTAMP(created)) date_submission,\n", 133 | "COUNT(*) as num_submissions\n", 134 | "FROM [fh-bigquery:reddit_posts.full_corpus_201509]\n", 135 | "GROUP BY date_submission\n", 136 | "ORDER by date_submission\"\n", 137 | "\n", 138 | "df <- tbl_df(query_exec(sql, project=project_name, max_pages=Inf))\n", 139 | "df %>% tail(10)" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "Now we can plot it in ggplot2:" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 19, 152 | "metadata": { 153 | "collapsed": false 154 | }, 155 | "outputs": [], 156 | "source": [ 157 | "plot <- ggplot(df, aes(x=as.Date(date_submission), y=num_submissions)) +\n", 158 | " geom_area(fill=\"#2980b9\", alpha=0.85, size=0) +\n", 159 | " fte_theme() +\n", 160 | " scale_x_date(breaks=date_breaks(\"1 year\"), labels=date_format(\"%Y\")) +\n", 161 | " scale_y_continuous(breaks=pretty_breaks(8), labels=comma) +\n", 162 | " labs(x=\"Date of Submission\", y=\"# of Submissions\", title=\"Daily # of Reddit Submissions from 2006 - 2015\")\n", 163 | "\n", 164 | "max_save(plot, \"reddit-bigquery-1\", \"Reddit\")" 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": {}, 170 | "source": [ 171 | "![](reddit-bigquery-1.png)" 172 | ] 173 | }, 174 | { 175 | "cell_type": "markdown", 176 | "metadata": {}, 177 | "source": [ 178 | "## When is the best time to submit to reddit for virality?\n", 179 | "\n", 180 | "Create heatmap." 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": 21, 186 | "metadata": { 187 | "collapsed": false 188 | }, 189 | "outputs": [ 190 | { 191 | "data": { 192 | "text/html": [ 193 | "\n", 194 | "\n", 195 | "\n", 196 | "\t\n", 197 | "\t\n", 198 | "\t\n", 199 | "\t\n", 200 | "\t\n", 201 | "\t\n", 202 | "\t\n", 203 | "\t\n", 204 | "\t\n", 205 | "\t\n", 206 | "\n", 207 | "
sub_dayofweeksub_hournum_gte_3000
17141001
2715893
3716890
4717806
5718807
6719763
7720769
8721705
9722620
10723505
\n" 208 | ], 209 | "text/latex": [ 210 | "\\begin{tabular}{r|lll}\n", 211 | " & sub_dayofweek & sub_hour & num_gte_3000\\\\\n", 212 | "\\hline\n", 213 | "\t1 & 7 & 14 & 1001\\\\\n", 214 | "\t2 & 7 & 15 & 893\\\\\n", 215 | "\t3 & 7 & 16 & 890\\\\\n", 216 | "\t4 & 7 & 17 & 806\\\\\n", 217 | "\t5 & 7 & 18 & 807\\\\\n", 218 | "\t6 & 7 & 19 & 763\\\\\n", 219 | "\t7 & 7 & 20 & 769\\\\\n", 220 | "\t8 & 7 & 21 & 705\\\\\n", 221 | "\t9 & 7 & 22 & 620\\\\\n", 222 | "\t10 & 7 & 23 & 505\\\\\n", 223 | "\\end{tabular}\n" 224 | ], 225 | "text/plain": [ 226 | "Source: local data frame [10 x 3]\n", 227 | "\n", 228 | " sub_dayofweek sub_hour num_gte_3000\n", 229 | " (int) (int) (int)\n", 230 | "1 7 14 1001\n", 231 | "2 7 15 893\n", 232 | "3 7 16 890\n", 233 | "4 7 17 806\n", 234 | "5 7 18 807\n", 235 | "6 7 19 763\n", 236 | "7 7 20 769\n", 237 | "8 7 21 705\n", 238 | "9 7 22 620\n", 239 | "10 7 23 505" 240 | ] 241 | }, 242 | "execution_count": 21, 243 | "metadata": {}, 244 | "output_type": "execute_result" 245 | } 246 | ], 247 | "source": [ 248 | "sql <- \"SELECT\n", 249 | " DAYOFWEEK(SEC_TO_TIMESTAMP(created - 60*60*5)) as sub_dayofweek,\n", 250 | " HOUR(SEC_TO_TIMESTAMP(created - 60*60*5)) as sub_hour,\n", 251 | " SUM(IF(score >= 3000, 1, 0)) as num_gte_3000,\n", 252 | "FROM [fh-bigquery:reddit_posts.full_corpus_201509]\n", 253 | "GROUP BY sub_dayofweek, sub_hour\n", 254 | "ORDER BY sub_dayofweek, sub_hour\"\n", 255 | "\n", 256 | "df <- tbl_df(query_exec(sql, project=project_name, max_pages=Inf))\n", 257 | "df %>% tail(10)" 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "metadata": {}, 263 | "source": [ 264 | "A few tweaks to format Time aliases into readable representations:" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": 25, 270 | "metadata": { 271 | "collapsed": false 272 | }, 273 | "outputs": [ 274 | { 275 | "name": "stderr", 276 | "output_type": "stream", 277 | "text": [ 278 | "Joining by: \"sub_dayofweek\"\n", 279 | "Joining by: \"sub_hour\"\n" 280 | ] 281 | }, 282 | { 283 | "data": { 284 | "text/html": [ 285 | "\n", 286 | "\n", 287 | "\n", 288 | "\t\n", 289 | "\t\n", 290 | "\t\n", 291 | "\t\n", 292 | "\t\n", 293 | "\t\n", 294 | "\t\n", 295 | "\t\n", 296 | "\t\n", 297 | "\t\n", 298 | "\n", 299 | "
sub_dayofweeksub_hournum_gte_3000dow_formathour_format
17141001Saturday2 PM
2715893Saturday3 PM
3716890Saturday4 PM
4717806Saturday5 PM
5718807Saturday6 PM
6719763Saturday7 PM
7720769Saturday8 PM
8721705Saturday9 PM
9722620Saturday10 PM
10723505Saturday11 PM
\n" 300 | ], 301 | "text/latex": [ 302 | "\\begin{tabular}{r|lllll}\n", 303 | " & sub_dayofweek & sub_hour & num_gte_3000 & dow_format & hour_format\\\\\n", 304 | "\\hline\n", 305 | "\t1 & 7 & 14 & 1001 & Saturday & 2 PM\\\\\n", 306 | "\t2 & 7 & 15 & 893 & Saturday & 3 PM\\\\\n", 307 | "\t3 & 7 & 16 & 890 & Saturday & 4 PM\\\\\n", 308 | "\t4 & 7 & 17 & 806 & Saturday & 5 PM\\\\\n", 309 | "\t5 & 7 & 18 & 807 & Saturday & 6 PM\\\\\n", 310 | "\t6 & 7 & 19 & 763 & Saturday & 7 PM\\\\\n", 311 | "\t7 & 7 & 20 & 769 & Saturday & 8 PM\\\\\n", 312 | "\t8 & 7 & 21 & 705 & Saturday & 9 PM\\\\\n", 313 | "\t9 & 7 & 22 & 620 & Saturday & 10 PM\\\\\n", 314 | "\t10 & 7 & 23 & 505 & Saturday & 11 PM\\\\\n", 315 | "\\end{tabular}\n" 316 | ], 317 | "text/plain": [ 318 | "Source: local data frame [10 x 5]\n", 319 | "\n", 320 | " sub_dayofweek sub_hour num_gte_3000 dow_format hour_format\n", 321 | " (int) (int) (int) (chr) (chr)\n", 322 | "1 7 14 1001 Saturday 2 PM\n", 323 | "2 7 15 893 Saturday 3 PM\n", 324 | "3 7 16 890 Saturday 4 PM\n", 325 | "4 7 17 806 Saturday 5 PM\n", 326 | "5 7 18 807 Saturday 6 PM\n", 327 | "6 7 19 763 Saturday 7 PM\n", 328 | "7 7 20 769 Saturday 8 PM\n", 329 | "8 7 21 705 Saturday 9 PM\n", 330 | "9 7 22 620 Saturday 10 PM\n", 331 | "10 7 23 505 Saturday 11 PM" 332 | ] 333 | }, 334 | "execution_count": 25, 335 | "metadata": {}, 336 | "output_type": "execute_result" 337 | } 338 | ], 339 | "source": [ 340 | "dow_format <- data_frame(sub_dayofweek = 1:7, dow_format = c(\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"))\n", 341 | "\n", 342 | "hour_format <- data_frame(sub_hour = 0:23, hour_format = c(paste(c(12,1:11),\"AM\"), paste(c(12,1:11),\"PM\")))\n", 343 | "\n", 344 | "df_time <- df %>% left_join(dow_format) %>% left_join(hour_format)\n", 345 | "\n", 346 | "df_time %>% tail(10)" 347 | ] 348 | }, 349 | { 350 | "cell_type": "code", 351 | "execution_count": 28, 352 | "metadata": { 353 | "collapsed": true 354 | }, 355 | "outputs": [], 356 | "source": [ 357 | "# Necessary for correct order when plotting.\n", 358 | "df_time$dow_format <- factor(df_time$dow_format, level = rev(dow_format$dow_format))\n", 359 | "df_time$hour_format <- factor(df_time$hour_format, level = hour_format$hour_format)\n", 360 | "\n", 361 | "plot <- ggplot(df_time, aes(x=hour_format, y=dow_format, fill=num_gte_3000)) +\n", 362 | " geom_tile() +\n", 363 | " fte_theme() +\n", 364 | " theme(axis.text.x = element_text(angle = 90, vjust = 0.6), legend.title = element_blank(), legend.position=\"top\", legend.direction=\"horizontal\", legend.key.width=unit(1, \"cm\"), legend.key.height=unit(0.25, \"cm\"), legend.margin=unit(-0.5,\"cm\"), panel.margin=element_blank()) +\n", 365 | " labs(x = \"Hour of Reddit Submission (Eastern Standard Time)\", y = \"Day of Week of Reddit Submission\", title = \"# of Reddit Submissions Which Received >3000 Points, by Time of Original Submission\") +\n", 366 | " scale_fill_gradient(low = \"white\", high = \"#27ae60\", labels=comma, breaks=pretty_breaks(6))\n", 367 | "\n", 368 | "max_save(plot, \"reddit-bigquery-2\", \"Reddit\", w=6)" 369 | ] 370 | }, 371 | { 372 | "cell_type": "markdown", 373 | "metadata": {}, 374 | "source": [ 375 | "![](reddit-bigquery-2.png)" 376 | ] 377 | }, 378 | { 379 | "cell_type": "markdown", 380 | "metadata": {}, 381 | "source": [ 382 | "# Which words in comments lead to the most upvotes?" 383 | ] 384 | }, 385 | { 386 | "cell_type": "code", 387 | "execution_count": 153, 388 | "metadata": { 389 | "collapsed": false 390 | }, 391 | "outputs": [ 392 | { 393 | "name": "stdout", 394 | "output_type": "stream", 395 | "text": [ 396 | "\r", 397 | "Running query: RUNNING 2.1s\r", 398 | "Running query: RUNNING 2.7s\r", 399 | "Running query: RUNNING 3.3s\n" 400 | ] 401 | }, 402 | { 403 | "name": "stderr", 404 | "output_type": "stream", 405 | "text": [ 406 | "11.3 gigabytes processed\n" 407 | ] 408 | }, 409 | { 410 | "data": { 411 | "text/html": [ 412 | "\n", 413 | "\n", 414 | "\n", 415 | "\t\n", 416 | "\t\n", 417 | "\t\n", 418 | "\t\n", 419 | "\t\n", 420 | "\t\n", 421 | "\t\n", 422 | "\t\n", 423 | "\t\n", 424 | "\t\n", 425 | "\n", 426 | "
wordnum_wordsavg_score
1the86068810.56031
2to5660549.885569
3a5103229.933583
4and41944910.13845
5of3873769.68622
6that3193368.988705
7is3104618.917468
8i2915338.348729
9you2831406.48695
10in2771309.831895
\n" 427 | ], 428 | "text/latex": [ 429 | "\\begin{tabular}{r|lll}\n", 430 | " & word & num_words & avg_score\\\\\n", 431 | "\\hline\n", 432 | "\t1 & the & 860688 & 10.56031\\\\\n", 433 | "\t2 & to & 566054 & 9.885569\\\\\n", 434 | "\t3 & a & 510322 & 9.933583\\\\\n", 435 | "\t4 & and & 419449 & 10.13845\\\\\n", 436 | "\t5 & of & 387376 & 9.68622\\\\\n", 437 | "\t6 & that & 319336 & 8.988705\\\\\n", 438 | "\t7 & is & 310461 & 8.917468\\\\\n", 439 | "\t8 & i & 291533 & 8.348729\\\\\n", 440 | "\t9 & you & 283140 & 6.48695\\\\\n", 441 | "\t10 & in & 277130 & 9.831895\\\\\n", 442 | "\\end{tabular}\n" 443 | ], 444 | "text/plain": [ 445 | "Source: local data frame [10 x 3]\n", 446 | "\n", 447 | " word num_words avg_score\n", 448 | " (chr) (int) (dbl)\n", 449 | "1 the 860688 10.560306\n", 450 | "2 to 566054 9.885569\n", 451 | "3 a 510322 9.933583\n", 452 | "4 and 419449 10.138446\n", 453 | "5 of 387376 9.686220\n", 454 | "6 that 319336 8.988705\n", 455 | "7 is 310461 8.917468\n", 456 | "8 i 291533 8.348729\n", 457 | "9 you 283140 6.486950\n", 458 | "10 in 277130 9.831895" 459 | ] 460 | }, 461 | "execution_count": 153, 462 | "metadata": {}, 463 | "output_type": "execute_result" 464 | } 465 | ], 466 | "source": [ 467 | "# In R, note that the backslashes and quotes are escaped.\n", 468 | "\n", 469 | "sql <- \"SELECT word, COUNT(*) as num_words, AVG(score) as avg_score\n", 470 | "FROM(FLATTEN((\n", 471 | " SELECT SPLIT(LOWER(REGEXP_REPLACE(body, r'[\\\\.\\\\\\\",*:()\\\\[\\\\]/|\\\\n]', ' ')), ' ') word, score\n", 472 | " FROM [fh-bigquery:reddit_comments.2015_08] \n", 473 | " WHERE author NOT IN (SELECT author FROM [fh-bigquery:reddit_comments.bots_201505])\n", 474 | " AND subreddit=\\\"news\\\"\n", 475 | " ), word))\n", 476 | "GROUP EACH BY word\n", 477 | "HAVING num_words >= 10000\n", 478 | "ORDER BY num_words DESC\"\n", 479 | "\n", 480 | "df <- tbl_df(query_exec(sql, project=project_name, max_pages=Inf))\n", 481 | "df %>% head(10)" 482 | ] 483 | }, 484 | { 485 | "cell_type": "markdown", 486 | "metadata": {}, 487 | "source": [ 488 | "Create a wordcloud using the `wordcloud` package. (I may do a seperate post on how to make Wordclouds.)" 489 | ] 490 | }, 491 | { 492 | "cell_type": "code", 493 | "execution_count": 161, 494 | "metadata": { 495 | "collapsed": false 496 | }, 497 | "outputs": [ 498 | { 499 | "data": { 500 | "text/html": [ 501 | "pdf: 2" 502 | ], 503 | "text/latex": [ 504 | "\\textbf{pdf:} 2" 505 | ], 506 | "text/markdown": [ 507 | "**pdf:** 2" 508 | ], 509 | "text/plain": [ 510 | "pdf \n", 511 | " 2 " 512 | ] 513 | }, 514 | "execution_count": 161, 515 | "metadata": {}, 516 | "output_type": "execute_result" 517 | } 518 | ], 519 | "source": [ 520 | "stop_words <- unlist(strsplit(\"a,able,about,across,after,all,almost,also,am,among,an,and,any,are,as,at,be,because,been,but,by,can,cannot,could,dear,did,do,does,either,else,ever,every,for,from,get,got,had,has,have,he,her,hers,him,his,how,however,i,if,in,into,is,it,its,just,least,let,like,likely,may,me,might,most,must,my,neither,no,nor,not,of,off,often,on,only,or,other,our,own,rather,said,say,says,she,should,since,so,some,than,that,the,their,them,then,there,these,they,this,tis,to,too,twas,us,wants,was,we,were,what,when,where,which,while,who,whom,why,will,with,would,yet,you,your,id,item,it\\'s,don\\'t\",\",\"))\n", 521 | "\n", 522 | "pal <- brewer.pal(9, \"Purples\")\n", 523 | "pal <- pal[-c(1:3)] # Remove light colors\n", 524 | "\n", 525 | "df_nostop <- df %>% filter(!(word %in% stop_words))\n", 526 | "\n", 527 | "png(filename = \"reddit-bigquery-3.png\", width = 1000, height = 1000, res= 300)\n", 528 | "\n", 529 | "wordcloud(toupper(df_nostop$word),\n", 530 | " df_nostop$num_words,\n", 531 | " scale=c(5,.1),\n", 532 | " random.order=F,\n", 533 | " rot.per=.10,\n", 534 | " max.words=5000,\n", 535 | " colors=pal,\n", 536 | " family=\"Avenir Next Condensed Bold\",\n", 537 | " random.color=T)\n", 538 | "\n", 539 | "dev.off()" 540 | ] 541 | }, 542 | { 543 | "cell_type": "markdown", 544 | "metadata": {}, 545 | "source": [ 546 | "![](reddit-bigquery-3.png)" 547 | ] 548 | }, 549 | { 550 | "cell_type": "markdown", 551 | "metadata": {}, 552 | "source": [ 553 | "# Subreddit Comment Monthly Active Users" 554 | ] 555 | }, 556 | { 557 | "cell_type": "code", 558 | "execution_count": 149, 559 | "metadata": { 560 | "collapsed": false 561 | }, 562 | "outputs": [ 563 | { 564 | "name": "stdout", 565 | "output_type": "stream", 566 | "text": [ 567 | "\r", 568 | "Running query: RUNNING 2.5s\r", 569 | "Running query: RUNNING 4.0s\r", 570 | "Running query: RUNNING 4.6s\r", 571 | "Running query: RUNNING 5.2s\r", 572 | "Running query: RUNNING 5.8s\r", 573 | "Running query: RUNNING 6.4s\r", 574 | "Running query: RUNNING 7.0s\r", 575 | "Running query: RUNNING 7.6s\r", 576 | "Running query: RUNNING 8.3s\r", 577 | "Running query: RUNNING 8.9s\r", 578 | "Running query: RUNNING 9.5s\r", 579 | "Running query: RUNNING 10.1s\r", 580 | "Running query: RUNNING 10.7s\r", 581 | "Running query: RUNNING 11.3s\r", 582 | "Running query: RUNNING 11.9s\n" 583 | ] 584 | }, 585 | { 586 | "name": "stderr", 587 | "output_type": "stream", 588 | "text": [ 589 | "53.3 gigabytes processed\n" 590 | ] 591 | }, 592 | { 593 | "data": { 594 | "text/html": [ 595 | "\n", 596 | "\n", 597 | "\n", 598 | "\t\n", 599 | "\t\n", 600 | "\t\n", 601 | "\t\n", 602 | "\t\n", 603 | "\t\n", 604 | "\t\n", 605 | "\t\n", 606 | "\t\n", 607 | "\t\n", 608 | "\n", 609 | "
subredditdateunique_authors
1news2015-08107419
2gifs2015-08106822
3movies2015-08101296
4AdviceAnimals2015-0899190
5Showerthoughts2015-0876849
6aww2015-0871682
7IAmA2015-0867675
8explainlikeimfive2015-0860421
9mildlyinteresting2015-0860346
10Music2015-0859769
\n" 610 | ], 611 | "text/latex": [ 612 | "\\begin{tabular}{r|lll}\n", 613 | " & subreddit & date & unique_authors\\\\\n", 614 | "\\hline\n", 615 | "\t1 & news & 2015-08 & 107419\\\\\n", 616 | "\t2 & gifs & 2015-08 & 106822\\\\\n", 617 | "\t3 & movies & 2015-08 & 101296\\\\\n", 618 | "\t4 & AdviceAnimals & 2015-08 & 99190\\\\\n", 619 | "\t5 & Showerthoughts & 2015-08 & 76849\\\\\n", 620 | "\t6 & aww & 2015-08 & 71682\\\\\n", 621 | "\t7 & IAmA & 2015-08 & 67675\\\\\n", 622 | "\t8 & explainlikeimfive & 2015-08 & 60421\\\\\n", 623 | "\t9 & mildlyinteresting & 2015-08 & 60346\\\\\n", 624 | "\t10 & Music & 2015-08 & 59769\\\\\n", 625 | "\\end{tabular}\n" 626 | ], 627 | "text/plain": [ 628 | "Source: local data frame [10 x 3]\n", 629 | "\n", 630 | " subreddit date unique_authors\n", 631 | " (chr) (chr) (int)\n", 632 | "1 news 2015-08 107419\n", 633 | "2 gifs 2015-08 106822\n", 634 | "3 movies 2015-08 101296\n", 635 | "4 AdviceAnimals 2015-08 99190\n", 636 | "5 Showerthoughts 2015-08 76849\n", 637 | "6 aww 2015-08 71682\n", 638 | "7 IAmA 2015-08 67675\n", 639 | "8 explainlikeimfive 2015-08 60421\n", 640 | "9 mildlyinteresting 2015-08 60346\n", 641 | "10 Music 2015-08 59769" 642 | ] 643 | }, 644 | "execution_count": 149, 645 | "metadata": {}, 646 | "output_type": "execute_result" 647 | } 648 | ], 649 | "source": [ 650 | "# Query is about 53GB; use with caution!\n", 651 | "\n", 652 | "sql <- \"SELECT subreddit, date, unique_authors FROM\n", 653 | "(SELECT subreddit, date, unique_authors, ROW_NUMBER() OVER (PARTITION BY date ORDER BY unique_authors DESC) rank FROM\n", 654 | "(SELECT subreddit, LEFT(DATE(SEC_TO_TIMESTAMP(created_utc)), 7) as date, COUNT(UNIQUE(author)) as unique_authors\n", 655 | "FROM TABLE_QUERY([fh-bigquery:reddit_comments], \\\"table_id CONTAINS \\'20\\' AND LENGTH(table_id)<8\\\")\n", 656 | "GROUP EACH BY subreddit, date\n", 657 | "))\n", 658 | "WHERE rank <= 20\n", 659 | "ORDER BY date ASC, unique_authors DESC\"\n", 660 | "\n", 661 | "df <- tbl_df(query_exec(sql, project=project_name, max_pages=Inf))\n", 662 | "df %>% tail(10)" 663 | ] 664 | }, 665 | { 666 | "cell_type": "code", 667 | "execution_count": 151, 668 | "metadata": { 669 | "collapsed": false 670 | }, 671 | "outputs": [], 672 | "source": [ 673 | "df_subreddit <- df %>% mutate(date_format=paste(date,\"-01\",sep=''))\n", 674 | "\n", 675 | "system(\"mkdir -p subreddit-ranks\")\n", 676 | "\n", 677 | "# Assign colors to subreddits at random using a hash of subreddit name\n", 678 | "\n", 679 | "colorHash <- function(strings) {\n", 680 | " colors <- color_palette\n", 681 | " \n", 682 | " if (strtoi(substr(digest(strings),1,6), base=36) %% length(colors) == 0) { return (\"#999999\") }\n", 683 | " return (colors[strtoi(substr(digest(strings),1,6), base=36) %% length(colors)])\n", 684 | "}\n", 685 | "\n", 686 | "subredditPlot <- function(month) {\n", 687 | " df_subset <- df_subreddit %>% filter(date_format==month)\n", 688 | " \n", 689 | " subreddit_colors <- unlist(lapply(df_subset$subreddit, colorHash))\n", 690 | "\n", 691 | " df_subset$subreddit <- factor(df_subset$subreddit, levels=rev(df_subset$subreddit))\n", 692 | " \n", 693 | " left_labels <- ifelse(df_subset$unique_authors > max(df_subset$unique_authors) * 0.90,\n", 694 | " format(df_subset$unique_authors, big.mark=\",\"), '')\n", 695 | " right_labels <- ifelse(df_subset$unique_authors < max(df_subset$unique_authors) * 0.90,\n", 696 | " format(df_subset$unique_authors, big.mark=\",\"), '')\n", 697 | " \n", 698 | " plot <- ggplot(df_subset, aes(x=subreddit, y=unique_authors, fill=subreddit)) +\n", 699 | " geom_bar(stat=\"identity\") +\n", 700 | " geom_text(label=left_labels, size=2, hjust=1.25, color=\"white\", family=\"Open Sans Condensed Bold\") +\n", 701 | " geom_text(label=right_labels, size=2, hjust=-0.25, color=subreddit_colors, family=\"Open Sans Condensed Bold\") +\n", 702 | " fte_theme() +\n", 703 | " coord_flip() +\n", 704 | " scale_y_continuous(labels=comma, breaks=pretty_breaks(6)) +\n", 705 | " scale_fill_manual(values=rev(subreddit_colors)) +\n", 706 | " theme(axis.text.y = element_text(color=rev(subreddit_colors)), plot.title=element_text(hjust=1), axis.title.y=element_blank()) +\n", 707 | " labs(y=\"Monthly Unique Commenters in Subreddit\", title=sprintf(\"Subreddits with Greatest # of Distinct Comment Authors in %s\", format(as.Date(month), \"%B %Y\")))\n", 708 | " \n", 709 | " \n", 710 | " max_save(plot, sprintf(\"subreddit-ranks/%s\", month), \"Reddit\")\n", 711 | " \n", 712 | "}\n", 713 | "\n", 714 | "subredditPlot(\"2015-08-01\")" 715 | ] 716 | }, 717 | { 718 | "cell_type": "markdown", 719 | "metadata": {}, 720 | "source": [ 721 | "![](subreddit-ranks/2015-08-01.png)" 722 | ] 723 | }, 724 | { 725 | "cell_type": "markdown", 726 | "metadata": {}, 727 | "source": [ 728 | "Loop over the `subredditPlot` function to create each frame for the GIF." 729 | ] 730 | }, 731 | { 732 | "cell_type": "code", 733 | "execution_count": 152, 734 | "metadata": { 735 | "collapsed": false 736 | }, 737 | "outputs": [], 738 | "source": [ 739 | "start_date <- \"2010-08-01\"\n", 740 | "\n", 741 | "months <- as.character(seq(as.Date(start_date), as.Date(\"2015-08-01\"), \"months\"))\n", 742 | "\n", 743 | "x <- lapply(months, subredditPlot)" 744 | ] 745 | }, 746 | { 747 | "cell_type": "markdown", 748 | "metadata": {}, 749 | "source": [ 750 | "![](subreddit-ranks.gif)" 751 | ] 752 | } 753 | ], 754 | "metadata": { 755 | "kernelspec": { 756 | "display_name": "R", 757 | "language": "R", 758 | "name": "ir" 759 | }, 760 | "language_info": { 761 | "codemirror_mode": "r", 762 | "file_extension": ".r", 763 | "mimetype": "text/x-r-source", 764 | "name": "R", 765 | "pygments_lexer": "r", 766 | "version": "3.1.2" 767 | } 768 | }, 769 | "nbformat": 4, 770 | "nbformat_minor": 0 771 | } 772 | -------------------------------------------------------------------------------- /subreddit-ranks.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks.gif -------------------------------------------------------------------------------- /subreddit-ranks/2010-08-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2010-08-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2010-09-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2010-09-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2010-10-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2010-10-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2010-11-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2010-11-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2010-12-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2010-12-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2011-01-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2011-01-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2011-02-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2011-02-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2011-03-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2011-03-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2011-04-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2011-04-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2011-05-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2011-05-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2011-06-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2011-06-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2011-07-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2011-07-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2011-08-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2011-08-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2011-09-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2011-09-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2011-10-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2011-10-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2011-11-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2011-11-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2011-12-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2011-12-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2012-01-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2012-01-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2012-02-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2012-02-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2012-03-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2012-03-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2012-04-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2012-04-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2012-05-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2012-05-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2012-06-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2012-06-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2012-07-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2012-07-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2012-08-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2012-08-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2012-09-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2012-09-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2012-10-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2012-10-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2012-11-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2012-11-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2012-12-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2012-12-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2013-01-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2013-01-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2013-02-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2013-02-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2013-03-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2013-03-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2013-04-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2013-04-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2013-05-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2013-05-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2013-06-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2013-06-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2013-07-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2013-07-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2013-08-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2013-08-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2013-09-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2013-09-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2013-10-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2013-10-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2013-11-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2013-11-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2013-12-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2013-12-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2014-01-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2014-01-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2014-02-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2014-02-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2014-03-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2014-03-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2014-04-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2014-04-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2014-05-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2014-05-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2014-06-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2014-06-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2014-07-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2014-07-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2014-08-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2014-08-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2014-09-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2014-09-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2014-10-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2014-10-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2014-11-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2014-11-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2014-12-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2014-12-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2015-01-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2015-01-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2015-02-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2015-02-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2015-03-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2015-03-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2015-04-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2015-04-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2015-05-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2015-05-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2015-06-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2015-06-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2015-07-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2015-07-01.png -------------------------------------------------------------------------------- /subreddit-ranks/2015-08-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minimaxir/reddit-bigquery/3925434482d2f5f118f1f81d2f48b4cba16822a1/subreddit-ranks/2015-08-01.png --------------------------------------------------------------------------------