

{"id":12332,"date":"2019-06-15T11:53:37","date_gmt":"2019-06-15T16:53:37","guid":{"rendered":"https:\/\/rud.is\/b\/?p=12332"},"modified":"2019-06-15T11:53:37","modified_gmt":"2019-06-15T16:53:37","slug":"introducing-the-ethercalc-package","status":"publish","type":"post","link":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/","title":{"rendered":"Introducing the {ethercalc} package"},"content":{"rendered":"<p>I mentioned <a href=\"https:\/\/rud.is\/b\/2019\/06\/11\/makeover-jumbalaya-beating-dumbbells-into-slopegraphs-whilst-orchestrating-ethercalc\/\">EtherCalc in a previous post<\/a> and managed to scrounge some time to put together a fledgling <a href=\"https:\/\/git.rud.is\/hrbrmstr\/ethercalc\"><code>{ethercalc} package<\/code><\/a> (it&#8217;s also on GitLab, SourceHut, Bitbucket and GitUgh, just sub out the appropriate URL prefix).<\/p>\n<p>I&#8217;m creating a package-specific Docker image (there are a couple out there but I&#8217;m not supporting their use with the package as they have a <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/CORS\">CORS<\/a> configuration that make EtherCalc API wrangling problematic) for EtherCalc but I would highly recommend that you just use it via the <code>npm<\/code> module. To do that you need a working Node.js installation and I highly recommended also running a local Redis instance (it&#8217;s super lightweight). Linux folks can use their fav package manager for that and macOS folks can use <code>homebrew<\/code>. Folks on the legacy Windows operating system can visit:<\/p>\n<ul>\n<li><a href=\"https:\/\/nodejs.org\/en\/download\/\">Download Node.js<\/a>,<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/get-npm\">Get npm<\/a>, and<\/li>\n<li><a href=\"https:\/\/redislabs.com\/blog\/redis-on-windows-10\/\">Running Redis on Windows 10<\/a><\/li>\n<\/ul>\n<p>to get EtherCalc going.<\/p>\n<p>I also recommend running EtherCalc and Redis together for performance reasons. EtherCalc will maintain a persistent store for your spreadsheets (they call them &#8220;rooms&#8221; since EtherCalc supports collaborative editing) with or without Redis, but using Redis makes all EtherCalc ops much, much faster.<\/p>\n<p>Once you have Redis running (on localhost, which is the default) and Node.js + <code>npm<\/code> installed, you can do the following to install EtherCalc:<\/p>\n<pre><code class=\"language-bash\">$ npm install -g ethercalc # may require `sudo` on some macOS or *nix systems\n<\/code><\/pre>\n<p>The <code>-g<\/code> tells <code>npm<\/code> to install the module globally and will work to ensure the <code>ethercalc<\/code> executable is on your <code>PATH<\/code>. Like many things one can install from Node.js or, even Python, you may see a cadre of &#8220;warnings&#8221; and possibly even some &#8220;errors&#8221;. If you execute the following and see similar messages:<\/p>\n<pre><code class=\"language-bash\">$ ethercalc --host=localhost ## IMPORTANT TO USE --host=localhost\nPlease connect to: http:\/\/localhost:8000\/\nStarting backend using webworker-threads\nFalling back to vm.CreateContext backend\nExpress server listening on port 8000 in development mode\nZappa 0.5.0 \"You can't do that on stage anymore\" orchestrating the show\nConnected to Redis Server: localhost:6379\n<\/code><\/pre>\n<p>and then go to the URL it gives you and you see something like this:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"12333\" data-permalink=\"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/ethercalc-splash\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?fit=2190%2C1588&amp;ssl=1\" data-orig-size=\"2190,1588\" 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=\"ethercalc-splash\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?fit=510%2C370&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?resize=510%2C370&#038;ssl=1\" alt=\"\" width=\"510\" height=\"370\" class=\"aligncenter size-large wp-image-12333\" srcset=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?resize=530%2C384&amp;ssl=1 530w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?resize=150%2C109&amp;ssl=1 150w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?resize=300%2C218&amp;ssl=1 300w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?resize=768%2C557&amp;ssl=1 768w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?resize=500%2C363&amp;ssl=1 500w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?resize=1200%2C870&amp;ssl=1 1200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?resize=400%2C290&amp;ssl=1 400w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?resize=800%2C580&amp;ssl=1 800w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?resize=200%2C145&amp;ssl=1 200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?w=1020&amp;ssl=1 1020w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-splash.png?w=1530&amp;ssl=1 1530w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/a><\/p>\n<p>then you&#8217;re all set to continue.<\/p>\n<h3>A [Very] Brief EtherCalc Introduction<\/h3>\n<p>EtherCalc <a href=\"https:\/\/github.com\/audreyt\/ethercalc\/wiki\">has a wiki<\/a>. As such, please hit that to get more info on EtherCalc.<\/p>\n<p>For now, if you hit that big, blue &#8220;Create Spreadsheet&#8221; button, you&#8217;ll see something pretty familiar if you&#8217;ve used Google Sheets, Excel, LibreOffice Calc (etc):<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"12334\" data-permalink=\"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/ethercalc-create\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?fit=2190%2C1588&amp;ssl=1\" data-orig-size=\"2190,1588\" 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=\"ethercalc-create\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?fit=510%2C370&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?resize=510%2C370&#038;ssl=1\" alt=\"\" width=\"510\" height=\"370\" class=\"aligncenter size-large wp-image-12334\" srcset=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?resize=530%2C384&amp;ssl=1 530w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?resize=150%2C109&amp;ssl=1 150w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?resize=300%2C218&amp;ssl=1 300w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?resize=768%2C557&amp;ssl=1 768w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?resize=500%2C363&amp;ssl=1 500w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?resize=1200%2C870&amp;ssl=1 1200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?resize=400%2C290&amp;ssl=1 400w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?resize=800%2C580&amp;ssl=1 800w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?resize=200%2C145&amp;ssl=1 200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?w=1020&amp;ssl=1 1020w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-create.png?w=1530&amp;ssl=1 1530w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/a><\/p>\n<p>If you start <code>ethercalc<\/code> without the <code>--host=localhost<\/code> it listens on all network interfaces, so other folks on your network can also use it as a local &#8220;cloud&#8221; spreadsheet app, but also <em>edit<\/em> with you, just like Google Sheets.<\/p>\n<p>I recommend playing around a bit in EtherCalc before continuing just to see that it is, indeed, a spreadsheet app like all the others you are familiar with, except it has a robust API that we can orchestrate from within R, now.<\/p>\n<h3>Working with {ethercalc}<\/h3>\n<p>You can install {ethercalc} from the aforelinked source or via:<\/p>\n<pre><code class=\"language-r\">install.packages(\"ethercalc\", repos = \"https:\/\/cinc.rud.is\")\n<\/code><\/pre>\n<p>where you&#8217;ll get a binary install for Windows and macOS (binary builds are for R 3.5.x but should also work for 3.6.x installs).<\/p>\n<p>If you don&#8217;t want to drop to a command line interface to start EtherCalc you can use <code>ec_start()<\/code> to run one that will <em>only be live during your R session<\/em>.<\/p>\n<p>Once you have EtherCalc running you&#8217;ll need to put the URL into an <code>ETHERCALC_HOST<\/code> environment variable. I recommend adding the following to <code>~\/.Renviron<\/code> and restarting your R session:<\/p>\n<pre><code class=\"language-bash\">ETHERCALC_HOST=http:\/\/localhost:8000\n<\/code><\/pre>\n<p>(You&#8217;ll get an interactive prompt to provide this if you don&#8217;t have the environment variable setup.)<\/p>\n<p>You can verify R can talk to your EtherCalc instance by executing <code>ec_running()<\/code> and reading the message or examining the (invisible) return value. Post a comment or file an issue (on your preferred social coding site) if you <em>really<\/em> think you&#8217;ve done <em>everything<\/em> right and still aren&#8217;t up and running by this point.<\/p>\n<p>The use-case I setup in the previous blog post was to perform light data entry since scraping was both prohibited and would have taken more time given how the visualization was made. To start a new spreadsheet (remember, EtherCalc folks call these &#8220;rooms&#8221;), just do:<\/p>\n<pre><code class=\"language-r\">ec_new(\"for-blog\")\n<\/code><\/pre>\n<p>And you should see this appear in your default web browser:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"12337\" data-permalink=\"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/ethercalc-new\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?fit=2190%2C1588&amp;ssl=1\" data-orig-size=\"2190,1588\" 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=\"ethercalc-new\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?fit=510%2C370&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?resize=510%2C370&#038;ssl=1\" alt=\"\" width=\"510\" height=\"370\" class=\"aligncenter size-large wp-image-12337\" srcset=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?resize=530%2C384&amp;ssl=1 530w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?resize=150%2C109&amp;ssl=1 150w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?resize=300%2C218&amp;ssl=1 300w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?resize=768%2C557&amp;ssl=1 768w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?resize=500%2C363&amp;ssl=1 500w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?resize=1200%2C870&amp;ssl=1 1200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?resize=400%2C290&amp;ssl=1 400w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?resize=800%2C580&amp;ssl=1 800w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?resize=200%2C145&amp;ssl=1 200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?w=1020&amp;ssl=1 1020w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-new.png?w=1530&amp;ssl=1 1530w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/a><\/p>\n<p>You can do <code>ec_list()<\/code> to see the names of all &#8220;saved&#8221; spreadsheets (<code>ec_delete()<\/code> can remove them, too).<\/p>\n<p>We&#8217;ll type in the values from the previous post:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"12338\" data-permalink=\"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/ethercalc-entry\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?fit=2190%2C1588&amp;ssl=1\" data-orig-size=\"2190,1588\" 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=\"ethercalc-entry\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?fit=510%2C370&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry-530x384.png?resize=510%2C370&#038;ssl=1\" alt=\"\" width=\"510\" height=\"370\" class=\"aligncenter size-large wp-image-12338\" srcset=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?resize=530%2C384&amp;ssl=1 530w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?resize=150%2C109&amp;ssl=1 150w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?resize=300%2C218&amp;ssl=1 300w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?resize=768%2C557&amp;ssl=1 768w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?resize=500%2C363&amp;ssl=1 500w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?resize=1200%2C870&amp;ssl=1 1200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?resize=400%2C290&amp;ssl=1 400w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?resize=800%2C580&amp;ssl=1 800w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?resize=200%2C145&amp;ssl=1 200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?w=1020&amp;ssl=1 1020w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-entry.png?w=1530&amp;ssl=1 1530w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/a><\/p>\n<p>Now, to retrieve those values, we can do:<\/p>\n<pre><code class=\"language-r\">ec_read(\"for-blog\", col_types=\"cii\")\n## # A tibble: 14 x 3\n##    topic                actually_read say_want_covered\n##    &lt;chr&gt;                        &lt;int&gt;            &lt;int&gt;\n##  1 Health care                      7                1\n##  2 Climate change                   5                2\n##  3 Education                       11                3\n##  4 Economics                        6                4\n##  5 Science                         10                7\n##  6 Technology                      14                8\n##  7 Business                        13               11\n##  8 National Security                1                5\n##  9 Politics                         2               10\n## 10 Sports                           3               14\n## 11 Immigration                      4                6\n## 12 Arts &amp; entertainment             8               13\n## 13 U.S. foreign policy              9                9\n## 14 Religion                        12               12\n<\/code><\/pre>\n<p>That function takes any (relevant to this package use-case) parameter that <code>readr::read_csv()<\/code> takes (since it uses that under the hood to parse the object that comes back from the API call). If someone adds or modifies any values you can just call <code>ec_read()<\/code> again to retrieve them.<\/p>\n<p>The <code>ec_export()<\/code> function lets you download the contents of the spreadsheet (&#8220;room&#8221;) to a local:<\/p>\n<ul>\n<li>CSV<\/li>\n<li>JSON<\/li>\n<li>HTML<\/li>\n<li>Markdown<\/li>\n<li>Excel<\/li>\n<\/ul>\n<p>file (and it also returns the raw data directly to the R session). So you can do something like:<\/p>\n<pre><code class=\"language-r\">cat(rawToChar(ec_export(\"for-blog\", \"md\", \"~\/Data\/survey.md\")))\n## |topic|actually_read|say_want_covered|\n## | ---- | ---- | ---- |\n## |Health care|7|1|\n## |Climate change|5|2|\n## |Education|11|3|\n## |Economics|6|4|\n## |Science|10|7|\n## |Technology|14|8|\n## |Business|13|11|\n## |National Security|1|5|\n## |Politics|2|10|\n## |Sports|3|14|\n## |Immigration|4|6|\n## |Arts &amp; entertainment|8|13|\n## |U.S. foreign policy|9|9|\n## |Religion|12|12|\n<\/code><\/pre>\n<p>You can also <em>append<\/em> to a spreadsheet right from R. We&#8217;ll sort that data frame (to prove the append is working and I&#8217;m not fibbing) and append it to the existing sheet (this is a toy example, but imagine appending to an always-running EtherCalc instance as a data logger, which folks actually do IRL):<\/p>\n<pre><code class=\"language-r\">ec_read(\"for-blog\", col_types=\"cii\") %&gt;% \n  dplyr::arrange(desc(topic)) %&gt;% \n  ec_append(\"for-blog\")\n<\/code><\/pre>\n<p><a href=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"12340\" data-permalink=\"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/ethercalc-append\/\" data-orig-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?fit=2190%2C1588&amp;ssl=1\" data-orig-size=\"2190,1588\" 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=\"ethercalc-append\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?fit=510%2C370&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?resize=510%2C370&#038;ssl=1\" alt=\"\" width=\"510\" height=\"370\" class=\"aligncenter size-large wp-image-12340\" srcset=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?resize=530%2C384&amp;ssl=1 530w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?resize=150%2C109&amp;ssl=1 150w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?resize=300%2C218&amp;ssl=1 300w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?resize=768%2C557&amp;ssl=1 768w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?resize=500%2C363&amp;ssl=1 500w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?resize=1200%2C870&amp;ssl=1 1200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?resize=400%2C290&amp;ssl=1 400w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?resize=800%2C580&amp;ssl=1 800w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?resize=200%2C145&amp;ssl=1 200w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?w=1020&amp;ssl=1 1020w, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?w=1530&amp;ssl=1 1530w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/a><\/p>\n<p>Note that you can open up EtherCalc to any existing spreadsheets (&#8220;rooms&#8221;) via <code>ec_view()<\/code> as well.<\/p>\n<h3>FIN<\/h3>\n<p>It&#8217;s worth noting that EtherCalc <em>appears<\/em> to have a limit of around 500,000 &#8220;cells&#8221; per spreadsheet (&#8220;room&#8221;). I mention that since if you try to, say, <code>ec_edit(ggplot2movies::movies, \"movies\")<\/code> you would have very likely crashed the running EtherCalc instance if I did not code in some guide rails into that function and the <code>ec_append()<\/code> function to stop you from doing that. It&#8217;s sane limit IMO an Google Sheets does something similar (per-tab) for the similar reasons (and both limits are one reason I&#8217;m still against using a browser for &#8220;everything&#8221; given the limitations of javascript wrangling of DOM elements).<\/p>\n<p>If you&#8217;re doing work on large-ish data, spreadsheets in general aren&#8217;t the best tools.<\/p>\n<p>And, while you should avoid hand-wrangling data at all costs, <code>ec_edit()<\/code> is a much faster and feature-rich alternative to R&#8217;s <code>edit()<\/code> function on most systems.<\/p>\n<p>I&#8217;ve shown off <em>most<\/em> of the current functionality of the <code>{ethercalc}<\/code> package in this post. One function I&#8217;ve left out is <code>ec_cmd()<\/code> which lets you completely orchestrate <em>all<\/em> EtherCalc operations. It&#8217;s powerful enough, and the EtherCalc command structure is gnarly enough, that we&#8217;ll have to cover it in a separate post. Also, stay tune for the aforementioned package-specific EtherCalc Docker image.<\/p>\n<p>Kick the tyres, contribute issues and\/or PRs as moved (and on your preferred social coding site) and see if both EtherCalc and <code>{ethercalc}<\/code> might work for you in place of or along with Excel and\/or Google Sheets.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I mentioned EtherCalc in a previous post and managed to scrounge some time to put together a fledgling {ethercalc} package (it&#8217;s also on GitLab, SourceHut, Bitbucket and GitUgh, just sub out the appropriate URL prefix). I&#8217;m creating a package-specific Docker image (there are a couple out there but I&#8217;m not supporting their use with the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":12340,"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-12332","post","type-post","status-publish","format-standard","has-post-thumbnail","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>Introducing the {ethercalc} package - 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\/2019\/06\/15\/introducing-the-ethercalc-package\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introducing the {ethercalc} package - rud.is\" \/>\n<meta property=\"og:description\" content=\"I mentioned EtherCalc in a previous post and managed to scrounge some time to put together a fledgling {ethercalc} package (it&#8217;s also on GitLab, SourceHut, Bitbucket and GitUgh, just sub out the appropriate URL prefix). I&#8217;m creating a package-specific Docker image (there are a couple out there but I&#8217;m not supporting their use with the [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/\" \/>\n<meta property=\"og:site_name\" content=\"rud.is\" \/>\n<meta property=\"article:published_time\" content=\"2019-06-15T16:53:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?fit=2190%2C1588&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"2190\" \/>\n\t<meta property=\"og:image:height\" content=\"1588\" \/>\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=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/\"},\"author\":{\"name\":\"hrbrmstr\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"headline\":\"Introducing the {ethercalc} package\",\"datePublished\":\"2019-06-15T16:53:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/\"},\"wordCount\":1061,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#\\\/schema\\\/person\\\/d7cb7487ab0527447f7fda5c423ff886\"},\"image\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2019\\\/06\\\/ethercalc-append.png?fit=2190%2C1588&ssl=1\",\"articleSection\":[\"R\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/\",\"url\":\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/\",\"name\":\"Introducing the {ethercalc} package - rud.is\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2019\\\/06\\\/ethercalc-append.png?fit=2190%2C1588&ssl=1\",\"datePublished\":\"2019-06-15T16:53:37+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2019\\\/06\\\/ethercalc-append.png?fit=2190%2C1588&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/rud.is\\\/b\\\/wp-content\\\/uploads\\\/2019\\\/06\\\/ethercalc-append.png?fit=2190%2C1588&ssl=1\",\"width\":2190,\"height\":1588},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/rud.is\\\/b\\\/2019\\\/06\\\/15\\\/introducing-the-ethercalc-package\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/rud.is\\\/b\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introducing the {ethercalc} package\"}]},{\"@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":"Introducing the {ethercalc} package - 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\/2019\/06\/15\/introducing-the-ethercalc-package\/","og_locale":"en_US","og_type":"article","og_title":"Introducing the {ethercalc} package - rud.is","og_description":"I mentioned EtherCalc in a previous post and managed to scrounge some time to put together a fledgling {ethercalc} package (it&#8217;s also on GitLab, SourceHut, Bitbucket and GitUgh, just sub out the appropriate URL prefix). I&#8217;m creating a package-specific Docker image (there are a couple out there but I&#8217;m not supporting their use with the [&hellip;]","og_url":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/","og_site_name":"rud.is","article_published_time":"2019-06-15T16:53:37+00:00","og_image":[{"width":2190,"height":1588,"url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?fit=2190%2C1588&ssl=1","type":"image\/png"}],"author":"hrbrmstr","twitter_card":"summary_large_image","twitter_misc":{"Written by":"hrbrmstr","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/#article","isPartOf":{"@id":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/"},"author":{"name":"hrbrmstr","@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"headline":"Introducing the {ethercalc} package","datePublished":"2019-06-15T16:53:37+00:00","mainEntityOfPage":{"@id":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/"},"wordCount":1061,"commentCount":3,"publisher":{"@id":"https:\/\/rud.is\/b\/#\/schema\/person\/d7cb7487ab0527447f7fda5c423ff886"},"image":{"@id":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?fit=2190%2C1588&ssl=1","articleSection":["R"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/","url":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/","name":"Introducing the {ethercalc} package - rud.is","isPartOf":{"@id":"https:\/\/rud.is\/b\/#website"},"primaryImageOfPage":{"@id":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/#primaryimage"},"image":{"@id":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?fit=2190%2C1588&ssl=1","datePublished":"2019-06-15T16:53:37+00:00","breadcrumb":{"@id":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/#primaryimage","url":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?fit=2190%2C1588&ssl=1","contentUrl":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2019\/06\/ethercalc-append.png?fit=2190%2C1588&ssl=1","width":2190,"height":1588},{"@type":"BreadcrumbList","@id":"https:\/\/rud.is\/b\/2019\/06\/15\/introducing-the-ethercalc-package\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/rud.is\/b\/"},{"@type":"ListItem","position":2,"name":"Introducing the {ethercalc} package"}]},{"@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\/2019\/06\/ethercalc-append.png?fit=2190%2C1588&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p23idr-3cU","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":3298,"url":"https:\/\/rud.is\/b\/2015\/03\/09\/new-r-package-ipapi-ipdomain-geolocation\/","url_meta":{"origin":12332,"position":0},"title":"New R Package &#8211; ipapi (IP\/Domain Geolocation)","author":"hrbrmstr","date":"2015-03-09","format":false,"excerpt":"I noticed that the @rOpenSci folks had an interface to [ip-api.com](http:\/\/ip-api.com\/) on their [ToDo](https:\/\/github.com\/ropensci\/webservices\/wiki\/ToDo) list so I whipped up a small R package to fill said gap. Their IP Geolocation API will take an IPv4, IPv6 or FQDN and kick back a ASN, lat\/lon, address and more. The [ipapi package](https:\/\/github.com\/hrbrmstr\/ipapi)\u2026","rel":"","context":"In &quot;cartography&quot;","block_context":{"text":"cartography","link":"https:\/\/rud.is\/b\/category\/cartography\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3574,"url":"https:\/\/rud.is\/b\/2015\/08\/02\/two-new-r-packages-qrencoder-passwordrandom\/","url_meta":{"origin":12332,"position":1},"title":"Two New R Packages &#8211; qrencoder &#038; passwordrandom","author":"hrbrmstr","date":"2015-08-02","format":false,"excerpt":"Believe it or not, there are two [1] [2] questions on @StackOverflowR about how to make QR codes in R. I personally think QR codes are kinda hokey, but who am I to argue with pressing needs of the #rstats community? I found libqrencode and it's highly brew-able and apt-able\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":6255,"url":"https:\/\/rud.is\/b\/2017\/09\/15\/its-a-fake-%f0%9f%93%a6-revisiting-trust-in-foss-ecosystems\/","url_meta":{"origin":12332,"position":2},"title":"It&#8217;s a FAKE (?)! Revisiting Trust In FOSS Ecosystems","author":"hrbrmstr","date":"2017-09-15","format":false,"excerpt":"I've blathered about trust before 1 2, but said blatherings were in a \"what if\" context. Unfortunately, the if has turned into a when, which begged for further blathering on a recent FOSS ecosystem cybersecurity incident. The gg_spiffy @thomasp85 linked to a post by the SK-CSIRT detailing the discovery and\u2026","rel":"","context":"In &quot;R&quot;","block_context":{"text":"R","link":"https:\/\/rud.is\/b\/category\/r\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/09\/download_counts_per_day-1.png?fit=1200%2C818&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/09\/download_counts_per_day-1.png?fit=1200%2C818&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/09\/download_counts_per_day-1.png?fit=1200%2C818&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/09\/download_counts_per_day-1.png?fit=1200%2C818&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/09\/download_counts_per_day-1.png?fit=1200%2C818&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":3841,"url":"https:\/\/rud.is\/b\/2016\/01\/03\/zellingenach-a-visual-exploration-of-the-spatial-patterns-in-the-endings-of-german-town-and-village-names-in-r\/","url_meta":{"origin":12332,"position":3},"title":"Zellingenach: A visual exploration of the spatial patterns in the endings of German town and village names in R","author":"hrbrmstr","date":"2016-01-03","format":false,"excerpt":"Moritz Stefaner started off 2016 with a [very spiffy post](http:\/\/truth-and-beauty.net\/experiments\/ach-ingen-zell\/) on _\"a visual exploration of the spatial patterns in the endings of German town and village names\"_. Moritz was [exploring some new data processing & visualization tools](https:\/\/github.com\/moritzstefaner\/ach-ingen-zell) for the post, but when I saw what he was doing I wondered\u2026","rel":"","context":"In &quot;cartography&quot;","block_context":{"text":"cartography","link":"https:\/\/rud.is\/b\/category\/cartography\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/01\/rud_is_zellingenach_html.png?fit=597%2C798&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/01\/rud_is_zellingenach_html.png?fit=597%2C798&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/01\/rud_is_zellingenach_html.png?fit=597%2C798&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":4852,"url":"https:\/\/rud.is\/b\/2017\/01\/08\/2017-01-authored-package-updates\/","url_meta":{"origin":12332,"position":4},"title":"2017-01 Authored Package Updates","author":"hrbrmstr","date":"2017-01-08","format":false,"excerpt":"The rest of the month is going to be super-hectic and it's unlikely I'll be able to do any more to help the push to CRAN 10K, so here's a breakdown of CRAN and GitHub new packages & package updates that I felt were worth raising awareness on: epidata I\u2026","rel":"","context":"In &quot;dplyr&quot;","block_context":{"text":"dplyr","link":"https:\/\/rud.is\/b\/category\/dplyr\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/01\/epi2.png?fit=982%2C1200&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/01\/epi2.png?fit=982%2C1200&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/01\/epi2.png?fit=982%2C1200&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2017\/01\/epi2.png?fit=982%2C1200&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":4345,"url":"https:\/\/rud.is\/b\/2016\/04\/17\/ggplot2-exercising-with-ggalt-dumbbells\/","url_meta":{"origin":12332,"position":5},"title":"(ggplot2) Exercising with (ggalt) dumbbells","author":"hrbrmstr","date":"2016-04-17","format":false,"excerpt":"I follow the most excellent Pew Research folks on Twitter to stay in tune with what's happening (statistically speaking) with the world. Today, they tweeted this excerpt from their 2015 Global Attitudes survey: The age gap in social media use around the world https:\/\/t.co\/0Dq1PcbExG pic.twitter.com\/9HBM7gLxwR\u2014 PewResearch Internet (@pewinternet) April 17,\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\/2016\/04\/RStudio.png?fit=811%2C1200&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/04\/RStudio.png?fit=811%2C1200&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/04\/RStudio.png?fit=811%2C1200&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/rud.is\/b\/wp-content\/uploads\/2016\/04\/RStudio.png?fit=811%2C1200&ssl=1&resize=700%2C400 2x"},"classes":[]}],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/12332","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=12332"}],"version-history":[{"count":0,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/posts\/12332\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media\/12340"}],"wp:attachment":[{"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/media?parent=12332"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/categories?post=12332"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rud.is\/b\/wp-json\/wp\/v2\/tags?post=12332"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}