

{"id":10827,"date":"2018-05-26T23:32:52","date_gmt":"2018-05-27T04:32:52","guid":{"rendered":"https:\/\/rud.is\/b\/?p=10827"},"modified":"2018-05-27T00:06:52","modified_gmt":"2018-05-27T05:06:52","slug":"the-power-of-standards-and-consistency","status":"publish","type":"post","link":"https:\/\/rud.is\/b\/2018\/05\/26\/the-power-of-standards-and-consistency\/","title":{"rendered":"The Power of Standards and Consistency"},"content":{"rendered":"<p>I&#8217;m going to (eventually) write a full post on the package I&#8217;m mentioning in this one : <a href=\"https:\/\/github.com\/hrbrmstr\/osqueryr\"><code>osqueryr<\/code>?<\/a>. The TLDR on <code>osqueryr<\/code> is that it is an R DBI wrapper (that has just enough glue to also be plugged into <code>dbplyr<\/code>) for <a href=\"https:\/\/code.facebook.com\/posts\/844436395567983\/introducing-osquery\/\"><code>osquery<\/code>?<\/a>. The TLDR on <code>osquery<\/code> is that it <em>&#8220;exposes an operating system as a high-performance relational database. This design allows you to write SQL-based queries efficiently and easily to explore operating systems.&#8221;<\/em><\/p>\n<p>In short, <code>osquery<\/code> turns the metadata and state information of your local system (or remote system(s)) into a SQL-compliant database. It also works on Windows, Linux, BSD and macOS. This means you can query a fleet of systems with a (mostly) normalized set of tables and get aggregated results. Operations and information security staff use this to manage systems and perform incident response tasks, but you can use it to get just about anything and there are even more powerful modes of operation for <code>osquery<\/code>. But, more on all the features of <code>osquery[r]<\/code> in another post.<\/p>\n<p>If you are skeptical, here&#8217;s some proof (which I need to show regardless of your skepticism state). First, a local &#8220;connection&#8221;:<\/p>\n<pre><code class=\"language-r\">\nlibrary(DBI)\nlibrary(osqueryr)\n\ncon <- DBI::dbConnect(Osquery())\n\nhead(dbListTables(con), 10)\n##  [1] \"account_policy_data\" \"acpi_tables\"         \"ad_config\"          \n##  [4] \"alf\"                 \"alf_exceptions\"      \"alf_explicit_auths\" \n##  [7] \"alf_services\"        \"app_schemes\"         \"apps\"               \n## [10] \"apt_sources\"\n\ndbListFields(con, \"processes\")\n##  [1] \"cmdline\"            \"cwd\"                \"disk_bytes_read\"   \n##  [4] \"disk_bytes_written\" \"egid\"               \"euid\"              \n##  [7] \"gid\"                \"name\"               \"nice\"              \n## [10] \"on_disk\"            \"parent\"             \"path\"              \n## [13] \"pgroup\"             \"pid\"                \"resident_size\"     \n## [16] \"root\"               \"sgid\"               \"start_time\"        \n## [19] \"state\"              \"suid\"               \"system_time\"       \n## [22] \"threads\"            \"total_size\"         \"uid\"               \n## [25] \"user_time\"          \"wired_size\"\n\ndbGetQuery(con, \"SELECT name, system_time FROM processes WHERE name LIKE '%fire%'\")\n## # A tibble: 2 x 2\n##   name     system_time\n## 1 Firewall 3          \n## 2 firefox  517846\n<\/code><\/pre>\n<p>then, a remote \"connection\":<\/p>\n<pre><code class=\"language-r\">\ncon2 <- osqueryr::dbConnect(Osquery(), host = \"hrbrmstr@osq1\")\n\nhead(dbListTables(con2), 10)\n##  [1] \"account_policy_data\" \"acpi_tables\"         \"ad_config\"          \n##  [4] \"alf\"                 \"alf_exceptions\"      \"alf_explicit_auths\" \n##  [7] \"alf_services\"        \"app_schemes\"         \"apps\"               \n## [10] \"apt_sources\"\n\ndbListFields(con2, \"processes\")\n##  [1] \"cmdline\"            \"cwd\"                \"disk_bytes_read\"   \n##  [4] \"disk_bytes_written\" \"egid\"               \"euid\"              \n##  [7] \"gid\"                \"name\"               \"nice\"              \n## [10] \"on_disk\"            \"parent\"             \"path\"              \n## [13] \"pgroup\"             \"pid\"                \"resident_size\"     \n## [16] \"root\"               \"sgid\"               \"start_time\"        \n## [19] \"state\"              \"suid\"               \"system_time\"       \n## [22] \"threads\"            \"total_size\"         \"uid\"               \n## [25] \"user_time\"          \"wired_size\"\n\ndbGetQuery(con2, \"SELECT name, system_time FROM processes WHERE name LIKE '%fire%'\")\n## # A tibble: 1 x 2\n##   name    system_time\n## 1 firefox 1071992\n<\/code><\/pre>\n<h3>\"You're talking an <em>awful<\/em> lot about the package when you said this was a post on 'standards' and 'consistency'.\"<\/h3>\n<p>True, but we needed that bit above for context. To explain what this post has to do with \"standards\" and \"consistency\" I also need to tell you a bit more about <em>how<\/em> both <code>osquery<\/code> and the <code>osqueryr<\/code> package are implemented.<\/p>\n<p>You can read about <code>osquery<\/code> in-depth starting at the link at the top of this post, but the authors of the tool <em>really<\/em> wanted a consistent idiom for accessing system metadata with usable, normalized output. They chose (to use a word they didn't but one that works for an R audience) a \"data frame\" as the output format and picked the universal language of \"data frames\" -- SQL -- as the inquiry interface. So, <em>right there<\/em> are examples of both standards and consistency: using SQL vs coming up with yet-another-query-language and avoiding the chaos of the myriad of outputs from various system commands by making all results conform to a rectangular data structure.<\/p>\n<p>Let's take this one-step further with a specific example. All modern operating systems have the concept of a \"process\" and said processes have (mostly) similar attributes. However, the commands used to get a detailed listing of those processes differ (sometimes wildly) from OS to OS. The authors of <code>osquery<\/code> came up with a set of <a href=\"https:\/\/osquery.io\/schema\/3.2.4\">schemas<\/a> to ensure a common, rectangular output and naming conventions (note that some schemas are unique to a particular OS since some elements of operating systems have no useful counterparts on other operating systems).<\/p>\n<p>The <code>osquery<\/code> authors also took consistency and standards to yet-another-level by taking advantage of a feature of SQLite called <a href=\"https:\/\/sqlite.org\/vtab.html\">virtual tables<\/a>. That enables them to have C\/C++\/Objective-C \"glue\" that gets called when a query is made so they can dispatch the intent to the proper functions or shell commands and then send all the results back -- <strong>or<\/strong> -- use the SQLite engine capabilities to do joining, filtering, UDF-calling, etc to produce rich, targeted rectangular output back.<\/p>\n<p>By not reinventing the wheel and relying on well-accepted features like data frames, SQL and SQLite the authors could direct all their focus on solving the problem they posited.<\/p>\n<h3>\"Um, you're talking alot about everything but R now.\"<\/h3>\n<p>We're getting to the good (i.e. \"R\") part now.<\/p>\n<p>Because the authors didn't try to become SQL parser writer experts and relied on the standard SQL offerings of SQLite, the queries made are \"real\" SQL (if you've worked with more than one database engine, you know how they all implement different flavours of SQL).<\/p>\n<p>Because these queries are \"real\" SQL, we can write an R <a href=\"https:\/\/github.com\/r-dbi\/DBI\">DBI<\/a> driver for it. The <code>DBI<\/code> package aims <em>\"[to define] a common interface between R and database management systems (DBMS). The interface defines a small set of classes and methods similar in spirit to Perl's DBI, Java's JDBC, Python's DB-API, and Microsoft's ODBC. It defines a set of classes and methods defines what operations are possible and how they are performed.\"<\/em><\/p>\n<p>If you look at the <code>osqueryr<\/code> package source, you'll see a bunch of DBI boilerplate code (which is in the <code>r-dbi<\/code> <a href=\"https:\/\/github.com\/r-dbi\">organization<\/a> example code) and only a handful of \"touch points\" for the actual calls to <code>osqueryi<\/code> (the command that processes SQL). No handling of anything but passing on SQL to the <code>osqueryi<\/code> engine and getting rectangular results back. By abstracting the system call details, R users can work with a familiar, consistent, standard interface and have full access to the power of <code>osquery<\/code> without firing up a terminal.<\/p>\n<p><em>But it gets even better.<\/em><\/p>\n<p>As noted above, one design aspect of <code>osquery<\/code> was to enable remote usage. Rather than come up with yet-another-daemon-and-custom-protocol, the <code>osquery<\/code> authors suggest <a href=\"https:\/\/www.openssh.com\/\"><code>ssh<\/code>?<\/a> as one way of invoking the command on remote systems and getting the rectangular results back.<\/p>\n<p>Because the <code>osqueryr<\/code> package used the <a href=\"https:\/\/github.com\/jeroen\/sys\"><code>sys<\/code>?<\/a> package for making local system calls, there was only a tiny bit of extra effort required to switch from <code>sys::exec_internal()<\/code> to a sibling call in the <a href=\"https:\/\/github.com\/ropensci\/ssh\"><code>ssh<\/code>?<\/a> package -- <code>ssh::ssh_exec_internal()<\/code> when remote connections were specified. (Said effort could have been zero if I chose a slightly different function in <code>sys<\/code>, too.)<\/p>\n<p>Relying on well-accepted standards made both <code>osqueryi<\/code> and the R DBI-driver work seamlessly without much code at all and definitely without a rats nest of nested <code>if<\/code>\/<code>else<\/code> statements and custom <code>httr<\/code> functions.<\/p>\n<h3>But it gets <em>even<\/em> more better-er<\/h3>\n<p>Some folks like &amp; grok SQL, others don't. (Humans have preferences, <em>go figure<\/em>.)<\/p>\n<p>A few years ago, Hadley (<em>do I even need to use his last name at this point in time?<\/em>) came up with the idea to have a more expressive and consistent way to work with data frames. We now know this as the <code>tidyverse<\/code> but one core element of the tidyverse is <code>dplyr<\/code>, which can really level-up your data frame game (no comments about <code>data.table<\/code>, or the beauty of base R, please). Not too long after the birth of <code>dplyr<\/code> came the ability to work with remote, rectangular, SQL-based data sources with (mostly) the same idioms.<\/p>\n<p>And, not too long after that, the remote <code>dplyr<\/code> interface (now, <code>dbplyr<\/code>) got up close and personal with <code>DBI<\/code>. Which ultimately means that if you make a  near-fully-compliant DBI interface to a SQL back-end you can now do something like this:<\/p>\n<pre><code class=\"language-r\">\nlibrary(DBI)\nlibrary(dplyr)\nlibrary(osqueryr)\n\ncon <- DBI::dbConnect(Osquery())\n\nosqdb <- src_dbi(con)\n\nprocs <- tbl(osqdb, \"processes\")\nlisten <- tbl(osqdb, \"listening_ports\")\n\nleft_join(procs, listen, by=\"pid\") %>%\n  filter(port != \"\", protocol == \"17\") %>% # 17 == TCP\n  distinct(name, port, address, pid)\n## # Source:   lazy query [?? x 4]\n## # Database: OsqueryConnection\n##    address name              pid   port \n##  1 0.0.0.0 BetterTouchTool   46317 57183\n##  2 0.0.0.0 Dropbox           1214  17500\n##  3 0.0.0.0 SystemUIServer    429   0    \n##  4 0.0.0.0 SystemUIServer    429   62240\n##  5 0.0.0.0 UserEventAgent    336   0    \n##  6 0.0.0.0 WiFiAgent         493   0    \n##  7 0.0.0.0 WiFiProxy         725   0    \n##  8 0.0.0.0 com.docker.vpnkit 732   0    \n##  9 0.0.0.0 identityservicesd 354   0    \n## 10 0.0.0.0 loginwindow       111   0    \n## # ... with more rows\n<\/code><\/pre>\n<p>The <code>src_dbi()<\/code> call wires up everything for us because <code>d[b]plyr<\/code> can rely on <code>DBI<\/code> doing it's standard &amp; consistent job and <code>DBI<\/code> can rely on the SQLite processing crunchy goodness of <code>osqueryi<\/code> to ultimately get us a list of really dangerous (if not firewalled off) processes that are listening on all network interfaces. (<em>Note to self: find out why the <code>BetterTouchTool<\/code> and <code>Dropbox<\/code> authors feel the need to bind to <code>0.0.0.0<\/code>&hellip;<\/em>)<\/p>\n<p>FIN<\/p>\n<p>What did standards and consistency get us?<\/p>\n<ul>\n<li>The <code>osquery<\/code> authors spent time solving a hard problem vs creating new data formats and protocols<\/li>\n<li>Rectangular data (i.e. \"data frame\") provides consistency and structure which ends up causing more freedom <\/li>\n<li>\"Standard\" SQL enables a consistent means to work with rectangular data<\/li>\n<li><code>ssh<\/code> normalizes (secure) access across systems with a consistent protocol<\/li>\n<li>A robust, well-defined standard mechanism for working with SQL databases enabled nigh instantaneous wiring up of a whole new back-end to R<\/li>\n<li><code>ssh<\/code> and <code>sys<\/code> common idioms made working with the new back-end on remote systems as easy as is on a local system<\/li>\n<li>Another robust, well-defined modern mechanism for working with rectangular data got wired up to this new back-end with (pretty much) one line of code because of the defined standard and expectation of consistency (and works for local and remote)<\/li>\n<\/ul>\n<p>Standards and consistency are <em>pretty darned cool<\/em>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m going to (eventually) write a full post on the package I&#8217;m mentioning in this one : osqueryr?. The TLDR on osqueryr is that it is an R DBI wrapper (that has just enough glue to also be plugged into dbplyr) for osquery?. The TLDR on osquery is that it &#8220;exposes an operating system as [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"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],"tags":[],"class_list":["post-10827","post","type-post","status-publish","format-standard","hentry","category-r"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>The Power of Standards and Consistency - 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\/2018\/05\/26\/the-power-of-standards-and-consistency\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The Power of Standards and Consistency - rud.is\" \/>\n<meta property=\"og:description\" content=\"I&#8217;m going to (eventually) write a full post on the package I&#8217;m mentioning in this one : osqueryr?. The TLDR on osqueryr is that it is an R DBI wrapper (that has just enough glue to also be plugged into dbplyr) for osquery?. The TLDR on osquery is that it &#8220;exposes an operating system as [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rud.is\/b\/2018\/05\/26\/the-power-of-standards-and-consistency\/\" \/>\n<meta property=\"og:site_name\" content=\"rud.is\" \/>\n<meta property=\"article:published_time\" content=\"2018-05-27T04:32:52+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-05-27T05:06:52+00:00\" \/>\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=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2018\\\/05\\\/26\\\/the-power-of-standards-and-consistency\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2018\\\/05\\\/26\\\/the-power-of-standards-and-consistency\\\/\"},\"author\":{\"name\":\"hrbrmstr\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"headline\":\"The Power of Standards and Consistency\",\"datePublished\":\"2018-05-27T04:32:52+00:00\",\"dateModified\":\"2018-05-27T05:06:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2018\\\/05\\\/26\\\/the-power-of-standards-and-consistency\\\/\"},\"wordCount\":1276,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"articleSection\":[\"R\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2018\\\/05\\\/26\\\/the-power-of-standards-and-consistency\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2018\\\/05\\\/26\\\/the-power-of-standards-and-consistency\\\/\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/2018\\\/05\\\/26\\\/the-power-of-standards-and-consistency\\\/\",\"name\":\"The Power of Standards and Consistency - rud.is\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\"},\"datePublished\":\"2018-05-27T04:32:52+00:00\",\"dateModified\":\"2018-05-27T05:06:52+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2018\\\/05\\\/26\\\/the-power-of-standards-and-consistency\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2018\\\/05\\\/26\\\/the-power-of-standards-and-consistency\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2018\\\/05\\\/26\\\/the-power-of-standards-and-consistency\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/rud.is\\\/b\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"The Power of Standards and Consistency\"}]},{\"@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":"The Power of Standards and Consistency - 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\/2018\/05\/26\/the-power-of-standards-and-consistency\/","og_locale":"en_US","og_type":"article","og_title":"The Power of Standards and Consistency - rud.is","og_description":"I&#8217;m going to (eventually) write a full post on the package I&#8217;m mentioning in this one : osqueryr?. The TLDR on osqueryr is that it is an R DBI wrapper (that has just enough glue to also be plugged into dbplyr) for osquery?. The TLDR on osquery is that it &#8220;exposes an operating system as [&hellip;]","og_url":"https:\/\/rud.is\/b\/2018\/05\/26\/the-power-of-standards-and-consistency\/","og_site_name":"rud.is","article_published_time":"2018-05-27T04:32:52+00:00","article_modified_time":"2018-05-27T05:06:52+00:00","author":"hrbrmstr","twitter_card":"summary_large_image","twitter_misc":{"Written by":"hrbrmstr","Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/rud.is\/b\/2018\/05\/26\/the-power-of-standards-and-consistency\/#article","isPartOf":{"@id":"https:\/\/rud.is\/b\/2018\/05\/26\/the-power-of-standards-and-consistency\/"},"author":{"name":"hrbrmstr","@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"headline":"The Power of Standards and Consistency","datePublished":"2018-05-27T04:32:52+00:00","dateModified":"2018-05-27T05:06:52+00:00","mainEntityOfPage":{"@id":"https:\/\/rud.is\/b\/2018\/05\/26\/the-power-of-standards-and-consistency\/"},"wordCount":1276,"commentCount":1,"publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"articleSection":["R"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/rud.is\/b\/2018\/05\/26\/the-power-of-standards-and-consistency\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/rud.is\/b\/2018\/05\/26\/the-power-of-standards-and-consistency\/","url":"https:\/\/rud.is\/b\/2018\/05\/26\/the-power-of-standards-and-consistency\/","name":"The Power of Standards and Consistency - rud.is","isPartOf":{"@id":"https:\/\/rud.is\/b\/#website"},"datePublished":"2018-05-27T04:32:52+00:00","dateModified":"2018-05-27T05:06:52+00:00","breadcrumb":{"@id":"https:\/\/rud.is\/b\/2018\/05\/26\/the-power-of-standards-and-consistency\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rud.is\/b\/2018\/05\/26\/the-power-of-standards-and-consistency\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/rud.is\/b\/2018\/05\/26\/the-power-of-standards-and-consistency\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/rud.is\/b\/"},{"@type":"ListItem","position":2,"name":"The Power of Standards and Consistency"}]},{"@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":"","jetpack_shortlink":"https:\/\/wp.me\/p23idr-2OD","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":10121,"url":"https:\/\/rud.is\/b\/2018\/04\/20\/painless-odbc-dplyr-connections-to-amazon-athena-and-apache-drill-with-r-odbc\/","url_meta":{"origin":10827,"position":0},"title":"Painless ODBC  + dplyr Connections to Amazon Athena and Apache Drill with R &#038; odbc","author":"hrbrmstr","date":"2018-04-20","format":false,"excerpt":"I spent some time this morning upgrading the JDBC driver (and changing up some supporting code to account for changes to it) for my metis package? which connects R up to Amazon Athena via RJDBC. I'm used to JDBC and have to deal with Java separately from R so I'm\u2026","rel":"","context":"In &quot;Apache Drill&quot;","block_context":{"text":"Apache Drill","link":"https:\/\/rud.is\/b\/category\/apache-drill\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/04\/today-is-a-good-day-to-query.jpg?fit=700%2C535&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/04\/today-is-a-good-day-to-query.jpg?fit=700%2C535&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/04\/today-is-a-good-day-to-query.jpg?fit=700%2C535&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2018\/04\/today-is-a-good-day-to-query.jpg?fit=700%2C535&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":9299,"url":"https:\/\/rud.is\/b\/2018\/03\/23\/on-mimes-software-versions-and-web-site-promiscuity-a-k-a-three-new-packages-to-round-out-the-week\/","url_meta":{"origin":10827,"position":1},"title":"On MIMEs, software versions and web site promiscuity (a.k.a. three new packages to round out the week)","author":"hrbrmstr","date":"2018-03-23","format":false,"excerpt":"A quick Friday post to let folks know about three in-development R packages that you're encouraged to poke the tyres o[fn] and also jump in and file issues or PRs for. Alleviating aversion to versions I introduced a \"version chart\" in a recent post and one key element of tagging\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":11088,"url":"https:\/\/rud.is\/b\/2018\/07\/26\/two-new-apache-drill-udfs-for-processing-urils-and-internet-domain-names\/","url_meta":{"origin":10827,"position":2},"title":"Two new Apache Drill UDFs for Processing UR[IL]s  and Internet Domain Names","author":"hrbrmstr","date":"2018-07-26","format":false,"excerpt":"Continuing the blog's UDF theme of late, there are two new UDF kids in town: drill-url-tools? for slicing & dicing URI\/URLs (just going to use 'URL' from now on in the post) drill-domain-tools? for slicing & dicing internet domain names (IDNs). Now, if you're an Apache Drill fanatic, you're likely\u2026","rel":"","context":"In &quot;Apache Drill&quot;","block_context":{"text":"Apache Drill","link":"https:\/\/rud.is\/b\/category\/apache-drill\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4753,"url":"https:\/\/rud.is\/b\/2016\/12\/20\/sergeant-a-r-boot-camp-for-apache-drill\/","url_meta":{"origin":10827,"position":3},"title":"sergeant : An R Boot Camp for Apache Drill","author":"hrbrmstr","date":"2016-12-20","format":false,"excerpt":"I recently mentioned that I've been working on a development version of an Apache Drill R package called sergeant. Here's a lifted \"TLDR\" on Drill: Drill supports a variety of NoSQL databases and file systems, including HBase, MongoDB, MapR-DB, HDFS, MapR-FS, Amazon S3, Azure Blob Storage, Google Cloud Storage, Swift,\u2026","rel":"","context":"In &quot;Apache Drill&quot;","block_context":{"text":"Apache Drill","link":"https:\/\/rud.is\/b\/category\/apache-drill\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":11921,"url":"https:\/\/rud.is\/b\/2019\/02\/17\/conquering-caffeinated-amazon-athena-with-the-metis-trio-of-packages\/","url_meta":{"origin":10827,"position":4},"title":"Conquering Caffeinated Amazon Athena with the metis Trio of Packages","author":"hrbrmstr","date":"2019-02-17","format":false,"excerpt":"I must preface this post with the posit that if you're doing anything interactive() with Amazon Athena you should seriously consider just using their free ODBC drivers as it's the easiest way to wire them up to R DBI- and tidyverse-wise. I've said as much in previous posts. Drop a\u2026","rel":"","context":"In &quot;athena&quot;","block_context":{"text":"athena","link":"https:\/\/rud.is\/b\/category\/athena\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":6154,"url":"https:\/\/rud.is\/b\/2017\/08\/13\/r%e2%81%b6-exploring-macos-applications-with-codesign-gatekeeper-r\/","url_meta":{"origin":10827,"position":5},"title":"R\u2076 \u2014 Exploring macOS Applications with codesign, Gatekeeper &#038; R","author":"hrbrmstr","date":"2017-08-13","format":false,"excerpt":"(General reminder abt \"R\u2076\" posts in that they are heavy on code-examples, minimal on expository. I try to design them with 2-3 \"nuggets\" embedded for those who take the time to walk through the code examples on their systems. I'll always provide further expository if requested in a comment, so\u2026","rel":"","context":"In &quot;macOS&quot;","block_context":{"text":"macOS","link":"https:\/\/rud.is\/b\/category\/macos\/"},"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\/10827","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=10827"}],"version-history":[{"count":0,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/10827\/revisions"}],"wp:attachment":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media?parent=10827"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/categories?post=10827"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/tags?post=10827"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}