

{"id":6930,"date":"2017-11-02T07:23:01","date_gmt":"2017-11-02T12:23:01","guid":{"rendered":"https:\/\/rud.is\/b\/?p=6930"},"modified":"2018-03-07T16:57:22","modified_gmt":"2018-03-07T21:57:22","slug":"yet-another-power-outages-post-full-tidyverse-edition","status":"publish","type":"post","link":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/","title":{"rendered":"Yet-Another-Power Outages Post : Full Tidyverse Edition"},"content":{"rendered":"<p>This past weekend, violent windstorms raged through New England. We &mdash; along with over 500,000 other Mainers &mdash; went &#8220;dark&#8221; in the wee hours of Monday morning and (this post was published on Thursday AM) we still have no utility-provided power nor high-speed internet access. The children have turned iFeral, and being a remote worker has been made that much more challenging. Earlier in the week, even making a cellular phone call (not an Google Voice or other VoIP-ish call, just pressing buttons in the phone &#8220;app&#8221; in iOS) resulted in an &#8220;All circuits are busy&#8221; message vs human contact. (I had to repair our generator at some point between then and now, but it&#8217;s all a blur at this point).<\/p>\n<p>Late Tuesday night, we checked the <a href=\"https:\/\/outagemap.cmpco.com\/cmp\/\">Central Maine Power outage info<\/a> and were greeted with a &#8220;November 4, 2017&#8221; estimate. After regaining composure, we doubled down on the fact that we&#8217;d be extreme indoor glamping for a while longer.<\/p>\n<p>As noted, I cope by coding and have a history of scraping Central Maine Power&#8217;s site for outage info. I ceased when I discovered the site &amp; twitter bot I mentioned in a recent post, as it does that for the entirety of the U.S. (though many power companies continue make it difficult to scrape their outage info).<\/p>\n<p>However, I wanted to see just how many other streets were in the same position as we are (I should note that less than a mile from us there are folks with power and internet, due mostly to their proximity to &#8220;vital&#8221; resources and how screwed up the Maine power grid is). Rather than reuse existing code, I wanted to make a modern, tidyverse edition of scrapers. If you follow enough paths in the aforementioned outage site, you&#8217;ll see that you eventually come to a page with a pretty ugly <code>iframe<\/code> that lets you poke around counties and towns. The following code traverses that tree to get street-level outage info:<\/p>\n<pre id=\"powerless01\"><code class=\"language-r\">library(rvest)\r\nlibrary(stringi)\r\nlibrary(hrbrthemes)\r\nlibrary(tidyverse)\r\n\r\n# helper to make numbers from comma strings; i still find it amusing that\r\n# this has never been a core &quot;S&quot; or base &quot;R&quot; function given that the\r\n# central goal of both languages are to work with data\r\nto_num &lt;- function(x) { as.numeric(stri_replace_all_fixed(x, &quot;,&quot;, &quot;&quot;)) }\r\n\r\n# top of the tree\r\npg &lt;- read_html(&quot;http:\/\/www3.cmpco.com\/OutageReports\/CMP.html&quot;)\r\n\r\n# basic idiom all the way down is to find the links to traverse until we get to\r\n# the street level data, plucking the timestamp of the CMP report along the way\r\nhtml_nodes(pg, &quot;a&quot;) %&gt;% \r\n  map_df(~{\r\n    \r\n    county &lt;- stri_trans_totitle(html_text(.x))\r\n    cpg &lt;- read_html(sprintf(&quot;http:\/\/www3.cmpco.com\/OutageReports\/%s&quot;, html_attr(.x, &quot;href&quot;)))\r\n        \r\n    message(sprintf(&quot;Processing %s...&quot;, county))\r\n    \r\n    html_nodes(cpg, xpath=&quot;.\/\/td[not(@colspan = &#039;2&#039;) and not(@align = &#039;right&#039;)][1]\/a&quot;) %&gt;% \r\n      map_df(~{\r\n        \r\n        town &lt;- stri_trans_totitle(html_text(.x))\r\n        tpg &lt;- read_html(sprintf(&quot;http:\/\/www3.cmpco.com\/OutageReports\/%s&quot;, html_attr(.x, &quot;href&quot;)))\r\n        \r\n        message(sprintf(&quot;  - %s&quot;, town))\r\n    \r\n        html_node(tpg, xpath=&quot;.\/\/td[contains(., &#039;Update:&#039;)]&quot;) %&gt;%\r\n          html_text() %&gt;%\r\n          stri_replace_first_regex(&quot;Update: &quot;, &quot;&quot;) %&gt;%\r\n          as.POSIXct(&quot;%b %d, %Y %I:%M %p&quot;, tz=&quot;America\/New_York&quot;) -&gt; ts\r\n        \r\n        html_node(tpg, &quot;table&quot;) %&gt;% \r\n          html_table() %&gt;% \r\n          docxtractr::assign_colnames(3) %&gt;%  \r\n          docxtractr::mcga() %&gt;% # in github version\r\n          mutate(street = stri_trans_totitle(street)) %&gt;% \r\n          mutate_at(vars(-estimated_restoration, -street), .funs=to_num) %&gt;% \r\n          filter(!is.na(total_customersby_street)) %&gt;% \r\n          mutate(timestamp = ts) %&gt;% \r\n          mutate(county = county) %&gt;% \r\n          mutate(town = town) %&gt;% \r\n          tbl_df()\r\n      })\r\n    \r\n  }) -&gt; xdf\r\n\r\nxdf &lt;- mutate(xdf, estimated_restoration = as.POSIXct(estimated_restoration, &quot;%b %d, %Y %I:%M %p&quot;, tz=&quot;America\/New_York&quot;))\r\n\r\nxdf\r\n## # A tibble: 10,601 x 7\r\n##           street total_customersby_street customerswithout_power estimated_restoration           timestamp       county   town\r\n##            &lt;chr&gt;                    &lt;dbl&gt;                  &lt;dbl&gt;                &lt;dttm&gt;              &lt;dttm&gt;        &lt;chr&gt;  &lt;chr&gt;\r\n##  1        2Nd St                       59                     14                    NA 2017-11-02 06:46:00 Androscoggin Auburn\r\n##  2        3Rd St                      128                     53                    NA 2017-11-02 06:46:00 Androscoggin Auburn\r\n##  3        4Th St                       89                     15                    NA 2017-11-02 06:46:00 Androscoggin Auburn\r\n##  4        5Th St                       56                      3                    NA 2017-11-02 06:46:00 Androscoggin Auburn\r\n##  5     Adams Ave                        4                      4   2017-11-03 19:00:00 2017-11-02 06:46:00 Androscoggin Auburn\r\n##  6     Allain St                        8                      8                    NA 2017-11-02 06:46:00 Androscoggin Auburn\r\n##  7     Atwood St                        6                      3   2017-11-04 22:00:00 2017-11-02 06:46:00 Androscoggin Auburn\r\n##  8    Baxter Ave                       32                      9   2017-11-04 22:00:00 2017-11-02 06:46:00 Androscoggin Auburn\r\n##  9     Beaver Rd                        9                      4   2017-11-04 22:00:00 2017-11-02 06:46:00 Androscoggin Auburn\r\n## 10 Bellflower Dr                       10                      9   2017-11-04 22:00:00 2017-11-02 06:46:00 Androscoggin Auburn\r\n## # ... with 10,591 more rows<\/code><\/pre>\n<p>One truly upsetting revelation from data is the number of folks still in an &#8220;Assessing&#8221; condition (i.e. no restoration time estimate):<\/p>\n<pre id=\"powerless02\"><code class=\"language-r\">filter(xdf, is.na(estimated_restoration)) %&gt;% \r\n  summarise(streets = n(), customers_impacted = sum(total_customersby_street))\r\n## # A tibble: 1 x 2\r\n##   streets customers_impacted\r\n##     &lt;int&gt;              &lt;dbl&gt;\r\n## 1    2255              42067<\/code><\/pre>\n<p>I&#8217;m thankful (for them and us) that Winter has not yet hit and that the weather has been and is going to be sufficiently mild to not make things life-threatening for most folks (it does get cold in northern Maine at this time of year).<\/p>\n<h3>It&#8217;s About Time<\/h3>\n<p>We can get an overview of when things are slated to get better for everyone but the folks I just mentioned:<\/p>\n<pre id=\"powerless03\"><code class=\"language-r\">select(xdf, county, estimated_restoration) %&gt;% \r\n  mutate(day = as.Date(estimated_restoration, tz=&quot;America\/New_York&quot;)) %&gt;% \r\n  filter(!is.na(day)) %&gt;%\r\n  count(day) %&gt;% \r\n  ggplot(aes(day, n)) +\r\n  geom_col() +\r\n  scale_x_date(date_labels = &quot;%b\\n%d&quot;, date_breaks = &quot;1 day&quot;) +\r\n  scale_y_comma() +\r\n  labs(\r\n    x=NULL, y=&quot;# Streets&quot;,\r\n    title=&quot;Distribution of Street Estimated Restoration Target Dates&quot;,\r\n    subtitle=sprintf(&quot;Central Maine Power \/ Generated: %s&quot;, Sys.time())\r\n  ) +\r\n  theme_ipsum_rc(grid=&quot;Y&quot;)<\/code><\/pre>\n<p><a href=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"6936\" data-permalink=\"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/plot_zoom_png-4\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png.png?fit=1490%2C780&amp;ssl=1\" data-orig-size=\"1490,780\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"plot_zoom_png\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png.png?fit=510%2C267&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png.png?resize=510%2C267&#038;ssl=1\" alt=\"\" width=\"510\" height=\"267\" class=\"aligncenter size-full wp-image-6936\" \/><\/a><\/p>\n<p>It seems that most of us are in the same &#8220;November 4th&#8221; bucket. But, we can also see that Central Maine Power&#8217;s data curation leaves much to be desired since there should be no dates in the past in that chart, but there are.<\/p>\n<p>With the scraping data above, we can explore the outage info in many ways, but &mdash; as time and bandwidth are precious commodities &mdash; I&#8217;ll leave you with the total number of customers still without power:<\/p>\n<pre id=\"powerless05\"><code class=\"language-r\">count(xdf, wt = customerswithout_power) %&gt;% pull(n)\r\n## [1] 153465<\/code><\/pre>\n<p>and, a county-level view of the outage:<\/p>\n<pre id=\"powerless04\"><code class=\"language-r\">select(xdf, county, estimated_restoration) %&gt;% \r\n  mutate(day = as.Date(estimated_restoration, tz=&quot;America\/New_York&quot;)) %&gt;% \r\n  filter(!is.na(day)) %&gt;% \r\n  count(county, day) %&gt;% \r\n  complete(county, day, fill=list(n=0)) %&gt;% \r\n  filter(day &gt;= Sys.Date()) %&gt;% \r\n  ggplot(aes(day, n)) +\r\n  geom_segment(aes(xend=day, yend=0), color=&quot;steelblue&quot;, size=4) +\r\n  scale_x_date(date_labels = &quot;%b\\n%d&quot;, date_breaks = &quot;1 day&quot;) +\r\n  scale_y_comma(limits=c(0,1250)) +\r\n  facet_wrap(~county, scales=&quot;free&quot;, ncol=5) +\r\n  labs(\r\n    x=NULL, y=&quot;# Streets&quot;,\r\n    title=&quot;Distribution of Street Estimated Restoration Target Dates by County&quot;,\r\n    subtitle=sprintf(&quot;Central Maine Power \/ Generated: %s&quot;, Sys.time())\r\n  ) +\r\n  theme_ipsum_rc(grid=&quot;Y&quot;, strip_text_face = &quot;bold&quot;, axis=&quot;xy&quot;) +\r\n  theme(panel.spacing.x=unit(3, &quot;lines&quot;)) +\r\n  theme(panel.spacing.y=unit(2, &quot;lines&quot;))<\/code><\/pre>\n<p><a href=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png-1.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"6938\" data-permalink=\"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/plot_zoom_png-1\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png-1.png?fit=2264%2C1368&amp;ssl=1\" data-orig-size=\"2264,1368\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"plot_zoom_png-1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png-1.png?fit=510%2C308&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png-1.png?resize=510%2C308&#038;ssl=1\" alt=\"\" width=\"510\" height=\"308\" class=\"aligncenter size-full wp-image-6938\" \/><\/a><\/p>\n<h3>FIN<\/h3>\n<p>In a way, I wish I had continued scraping CMP data since the power outages site I mentioned doesn&#8217;t seem to provide access to the raw data and getting a historical perspective of the outage locations and analyzing by geography and other demographics might be interesting.<\/p>\n<p>Hopefully the scraping code will be useful for some folks. It was definitely therapeutic for me :-)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This past weekend, violent windstorms raged through New England. We &mdash; along with over 500,000 other Mainers &mdash; went &#8220;dark&#8221; in the wee hours of Monday morning and (this post was published on Thursday AM) we still have no utility-provided power nor high-speed internet access. The children have turned iFeral, and being a remote worker [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":6936,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[91,725],"tags":[810],"class_list":["post-6930","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-r","category-web-scraping","tag-post"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Yet-Another-Power Outages Post : Full Tidyverse Edition - rud.is<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Yet-Another-Power Outages Post : Full Tidyverse Edition - rud.is\" \/>\n<meta property=\"og:description\" content=\"This past weekend, violent windstorms raged through New England. We &mdash; along with over 500,000 other Mainers &mdash; went &#8220;dark&#8221; in the wee hours of Monday morning and (this post was published on Thursday AM) we still have no utility-provided power nor high-speed internet access. The children have turned iFeral, and being a remote worker [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/\" \/>\n<meta property=\"og:site_name\" content=\"rud.is\" \/>\n<meta property=\"article:published_time\" content=\"2017-11-02T12:23:01+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-03-07T21:57:22+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png.png?fit=1490%2C780&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1490\" \/>\n\t<meta property=\"og:image:height\" content=\"780\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"hrbrmstr\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"hrbrmstr\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/\"},\"author\":{\"name\":\"hrbrmstr\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"headline\":\"Yet-Another-Power Outages Post : Full Tidyverse Edition\",\"datePublished\":\"2017-11-02T12:23:01+00:00\",\"dateModified\":\"2018-03-07T21:57:22+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/\"},\"wordCount\":607,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"image\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/plot_zoom_png.png?fit=1490%2C780&ssl=1\",\"keywords\":[\"post\"],\"articleSection\":[\"R\",\"web scraping\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/\",\"name\":\"Yet-Another-Power Outages Post : Full Tidyverse Edition - rud.is\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/plot_zoom_png.png?fit=1490%2C780&ssl=1\",\"datePublished\":\"2017-11-02T12:23:01+00:00\",\"dateModified\":\"2018-03-07T21:57:22+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/plot_zoom_png.png?fit=1490%2C780&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/plot_zoom_png.png?fit=1490%2C780&ssl=1\",\"width\":1490,\"height\":780},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2017\\\/11\\\/02\\\/yet-another-power-outages-post-full-tidyverse-edition\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/rud.is\\\/b\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Yet-Another-Power Outages Post : Full Tidyverse Edition\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/\",\"name\":\"rud.is\",\"description\":\"&quot;In God we trust. All others must bring data&quot;\",\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/rud.is\\\/b\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\",\"name\":\"hrbrmstr\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\",\"width\":460,\"height\":460,\"caption\":\"hrbrmstr\"},\"logo\":{\"@id\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2023\\\/10\\\/ukr-shield.png?fit=460%2C460&ssl=1\"},\"description\":\"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7\",\"sameAs\":[\"http:\\\/\\\/rud.is\"],\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/author\\\/hrbrmstr\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Yet-Another-Power Outages Post : Full Tidyverse Edition - rud.is","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/","og_locale":"en_US","og_type":"article","og_title":"Yet-Another-Power Outages Post : Full Tidyverse Edition - rud.is","og_description":"This past weekend, violent windstorms raged through New England. We &mdash; along with over 500,000 other Mainers &mdash; went &#8220;dark&#8221; in the wee hours of Monday morning and (this post was published on Thursday AM) we still have no utility-provided power nor high-speed internet access. The children have turned iFeral, and being a remote worker [&hellip;]","og_url":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/","og_site_name":"rud.is","article_published_time":"2017-11-02T12:23:01+00:00","article_modified_time":"2018-03-07T21:57:22+00:00","og_image":[{"width":1490,"height":780,"url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png.png?fit=1490%2C780&ssl=1","type":"image\/png"}],"author":"hrbrmstr","twitter_card":"summary_large_image","twitter_misc":{"Written by":"hrbrmstr","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/#article","isPartOf":{"@id":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/"},"author":{"name":"hrbrmstr","@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"headline":"Yet-Another-Power Outages Post : Full Tidyverse Edition","datePublished":"2017-11-02T12:23:01+00:00","dateModified":"2018-03-07T21:57:22+00:00","mainEntityOfPage":{"@id":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/"},"wordCount":607,"commentCount":2,"publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"image":{"@id":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png.png?fit=1490%2C780&ssl=1","keywords":["post"],"articleSection":["R","web scraping"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/","url":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/","name":"Yet-Another-Power Outages Post : Full Tidyverse Edition - rud.is","isPartOf":{"@id":"https:\/\/rud.is\/b\/#website"},"primaryImageOfPage":{"@id":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/#primaryimage"},"image":{"@id":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png.png?fit=1490%2C780&ssl=1","datePublished":"2017-11-02T12:23:01+00:00","dateModified":"2018-03-07T21:57:22+00:00","breadcrumb":{"@id":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/#primaryimage","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png.png?fit=1490%2C780&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png.png?fit=1490%2C780&ssl=1","width":1490,"height":780},{"@type":"BreadcrumbList","@id":"https:\/\/rud.is\/b\/2017\/11\/02\/yet-another-power-outages-post-full-tidyverse-edition\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/rud.is\/b\/"},{"@type":"ListItem","position":2,"name":"Yet-Another-Power Outages Post : Full Tidyverse Edition"}]},{"@type":"WebSite","@id":"https:\/\/rud.is\/b\/#website","url":"https:\/\/rud.is\/b\/","name":"rud.is","description":"&quot;In God we trust. All others must bring data&quot;","publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/rud.is\/b\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886","name":"hrbrmstr","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1","width":460,"height":460,"caption":"hrbrmstr"},"logo":{"@id":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2023\/10\/ukr-shield.png?fit=460%2C460&ssl=1"},"description":"Don't look at me\u2026I do what he does \u2014 just slower. #rstats avuncular \u2022 ?Resistance Fighter \u2022 Cook \u2022 Christian \u2022 [Master] Chef des Donn\u00e9es de S\u00e9curit\u00e9 @ @rapid7","sameAs":["http:\/\/rud.is"],"url":"https:\/\/rud.is\/b\/author\/hrbrmstr\/"}]}},"jetpack_featured_media_url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/11\/plot_zoom_png.png?fit=1490%2C780&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p23idr-1NM","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":24705,"url":"https:\/\/rud.is\/b\/2025\/03\/15\/call-to-action-state-department-power-grab\/","url_meta":{"origin":6930,"position":0},"title":"Call To Action: State Department Power Grab","author":"hrbrmstr","date":"2025-03-15","format":false,"excerpt":"(Re-posted from 47 Watch). The State Department, under the stewardship of Secretary Marco Rubio, has just dropped a bombshell determination that's about as subtle as a foghorn in a library. You can\/should review the Federal Register notice before continuing. There is a markdown formatted version of this on the 47\u2026","rel":"","context":"In &quot;Commentary&quot;","block_context":{"text":"Commentary","link":"https:\/\/rud.is\/b\/category\/commentary\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2793,"url":"https:\/\/rud.is\/b\/2013\/11\/27\/mapping-power-outages-in-maine-with-r\/","url_meta":{"origin":6930,"position":1},"title":"Mapping Power Outages In Maine With R","author":"hrbrmstr","date":"2013-11-27","format":false,"excerpt":"UPDATE: A Shiny (dynamic) version of this is now available. We had yet-another power outage this morning due to the weird weather patterns of the week and it was the final catalyst I needed to crank out some R code to map the affected counties. Central Maine Power provides an\u2026","rel":"","context":"In &quot;Charts &amp; Graphs&quot;","block_context":{"text":"Charts &amp; Graphs","link":"https:\/\/rud.is\/b\/category\/charts-graphs\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2013\/11\/Plot_Zoom.png?fit=530%2C680&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2013\/11\/Plot_Zoom.png?fit=530%2C680&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2013\/11\/Plot_Zoom.png?fit=530%2C680&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":12830,"url":"https:\/\/rud.is\/b\/2020\/11\/08\/its-almost-over-much-damage-has-been-done-but-i-we-have-a-call-to-unexpected-action\/","url_meta":{"origin":6930,"position":2},"title":"It&#8217;s [Almost] Over; Much Damage Has Been Done; But I [We] Have A Call To Unexpected Action","author":"hrbrmstr","date":"2020-11-08","format":false,"excerpt":"NOTE: There's a unique feed URL for R\/tech stuff \u2014 https:\/\/rud.is\/b\/category\/r\/feed\/. If you hit the generic \"subscribe\" button b\/c the vast majority of posts have been on that, this isn't one of those posts and you should probably delete it and move on with more important things than the rantings\u2026","rel":"","context":"In &quot;Commentary&quot;","block_context":{"text":"Commentary","link":"https:\/\/rud.is\/b\/category\/commentary\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":12510,"url":"https:\/\/rud.is\/b\/2019\/09\/14\/twitter-account-analysis-in-r\/","url_meta":{"origin":6930,"position":3},"title":"Twitter &#8220;Account Analysis&#8221; in R","author":"hrbrmstr","date":"2019-09-14","format":false,"excerpt":"This past week @propublica linked to a really spiffy resource for getting an overview of a Twitter user's profile and activity called accountanalysis. It has a beautiful interface that works as well on mobile as it does in a real browser. It also is fully interactive and supports cross-filtering (zoom\u2026","rel":"","context":"In &quot;R&quot;","block_context":{"text":"R","link":"https:\/\/rud.is\/b\/category\/r\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1191,"url":"https:\/\/rud.is\/b\/2012\/06\/07\/slopegraphs-in-python-exploring-binningrounding\/","url_meta":{"origin":6930,"position":4},"title":"Slopegraphs in Python \u2013 Exploring Binning\/Rounding","author":"hrbrmstr","date":"2012-06-07","format":false,"excerpt":"One of the last items for the 1.0 release is support for multiple columns of data. That will require some additional refactoring, so I've been procrastinating by exploring the recent \"fudging\" discovery. Despite claims to the contrary on other sites, there are more folks playing with slopegraphs than you might\u2026","rel":"","context":"In &quot;Charts &amp; Graphs&quot;","block_context":{"text":"Charts &amp; Graphs","link":"https:\/\/rud.is\/b\/category\/charts-graphs\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":270,"url":"https:\/\/rud.is\/b\/2011\/02\/28\/post-theftloss-response-recovery-with-evernote\/","url_meta":{"origin":6930,"position":5},"title":"Post-theft\/loss Response &#038; Recovery With Evernote","author":"hrbrmstr","date":"2011-02-28","format":false,"excerpt":"Last night, the kids left the garage open after sledding all afternoon and I failed to perform my usual rounds due to still being horrendously ill. At some point between 23:00 & 05:30, miscreants did a snatch & grab on some electronics and other items. Ugh. This was both a\u2026","rel":"","context":"In &quot;Physical Security&quot;","block_context":{"text":"Physical Security","link":"https:\/\/rud.is\/b\/category\/physical-security\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/6930","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/comments?post=6930"}],"version-history":[{"count":0,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/6930\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media\/6936"}],"wp:attachment":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media?parent=6930"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/categories?post=6930"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/tags?post=6930"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}