Rstudio Server On A Chromebook

The only post I got around to writing in 2017 was a single messy, evoloving set of notes on how to set up a Chromebook with R and RStudio. This post is a reprise of that one as well as post #1 in my effort to double my blog output from 2017 (I’m shooting for the stars on that goal). In this post I will detail how to set up RStudio Server in a crouton chroot and access it directly via Chrome without having to fire up a separate X11 window.

Why RStudio Server?

I have been succesfully using RStudio Desktop on my Chromebook all year and it has worked great. But there have been a few issues that have kind of bothered me. The top four of these are: opening web pages from RStudio, opening documents (PDF or Word), overall look and feel, and (the big one) not being able to pull out a source tab into a separate window. None of these are deal breakers, but they did lead to a bit of a bumpy workflow at times. I did not have these problems when accessing RStudio Server in the browser, but I don’t want to pay for servers to host RStudio Server nor do I want to require an internet connection to work. I figured I could stand up RStudio Server in a chroot, access it directly in Chrome via localhost and have a much more native ChromeOS feeling experience.

The long and short of it is that it is pretty easy to get set up (if you are comfortable setting up crouton) and the overall experience is much improved with web pages and documents just opening up in new tabs as you’d expect. The biggest improvement is now I can pull out those source tabs into a stand alone window and take advantage of the real estate of dual screens!

So enough yammering, how do you do it?

Install crouton and set up your chroot

There are a lot of great resources for installing crouton so no need for me to go over that again. In particular take a look at Jenny Bryan’s notes and the crouton repository

For RStudio Server we don’t need a full desktop so I decided to try this with a minimal install. I chose core and cli-extra because, frankly, I didn’t know the difference between the two and was just playing it safe. You can choose to encrypt the chroot or not. I didn’t as I was playing around with auto-starting the chroot when Chrome OS starts (see here for more on that). Never got that part of it working right.

update 2018-01-28: With just core and cli-extra you are missing a few things. Most notably for me, sound was not working correctly. And well, I need Rasmus Bååth’s beepr package. Adding the extension target fixed this.

update 2018-01-30: While extension fixed the audio issue, I was still having problems with RStudio Server and R Session getting discombobulated. I tried a full desktop install and that appears to be working much better. So the idea of using the minimal install wasn’t so great as some needed tooling was obviously missing. The rest of this post has been updated to reflect this.

Anyway, here is what I used to get my chroot set up.

sudo sh ~/Downloads/crouton -t xfce,extension -n rstudio

Once that finishes (it takes a while), you can hop into the chroot with

sudo enter-chroot

Install R

With a shiny new chroot started, we can now start all of our installs. First one is R.

sudo echo "deb http://cran.rstudio.com/bin/linux/ubuntu xenial/" | sudo tee -a /etc/apt/sources.list
gpg --keyserver keyserver.ubuntu.com --recv-key E084DAB9
gpg -a --export E084DAB9 | sudo apt-key add -
sudo apt-get update
sudo apt-get install r-base r-base-dev

Install RStudio Server

Next, we need to install RStudio Server. This grabs the latest and greatest version as of January 2018. I choose to delete the .deb just to keep the footprint of this thing to a minimum.

sudo apt-get install gdebi-core
wget https://download2.rstudio.org/rstudio-server-1.1.419-amd64.deb
sudo gdebi rstudio-server-1.1.419-amd64.deb
rm rstudio-server-1.1.419-amd64.deb

As an aside, I got distracted when I started working on this section. I wanted to be able to download the current version of RStudio Server without actually knowing what that version was. Luckily, RStudio lists those as XML at https://downloads2.rstudio.org. Unluckily, I know next to nothing about working with XML so this code certainly reflects that as I convert to string and parse that for the current version. If you are interested, here’s the function that gets the current version of RStudio Server. Also if you have thoughts on a more direct root (seems like it could be done within the XML itself), let me know in the comments.

get_rstudio_server <- function(arch = c("amd64","i386","i686","x86_64"),
                               file_type = c(".deb",".rpm"),
                               pro = FALSE, get = TRUE){
  arch <- match.arg(arch)
  file_type <- match.arg(file_type)
  url <- 'https://download2.rstudio.org'
  dat <- xml2::read_xml(url)
  dat_txt <- xml2::xml_text(xml2::xml_children(dat)) 
  current <- dat_txt[stringr::str_detect(dat_txt,"current")]
  current_date <- stringr::str_sub(current,12,21)
  deb_files <- dat_txt[stringr::str_detect(dat_txt,current_date)]
  deb_files <- deb_files[stringr::str_detect(deb_files,paste0(arch,file_type))]
  if(length(deb_files) == 0){
    stop("Not a valid arch and file_type combination")
  }
  if(pro){
    deb_file <- deb_files[stringr::str_detect(deb_files, "pro")]
  } else {
    deb_file <- deb_files[!stringr::str_detect(deb_files, "pro")]
  }
  deb_file <- stringr::str_sub(deb_file,1,
                               stringr::str_locate(deb_file,current_date)[1]-1)
  deb_file <- deb_file[1]
  if(get){
    httr::GET(paste0(url,"/",deb_file),httr::write_disk(deb_file, overwrite = TRUE),
              httr::progress())
  }
  deb_file
}

Open up firewall

Since this is RStudio server, we will be accessing it via Chrome and will need to make sure the requests get through the chroot’s firewall. We need to open that up to do so. I include the nano install because it is a little easier to work with than vim.

sudo apt-get install nano
sudo nano /etc/rc.local

Then add /sbin/iptables -I INPUT -p tcp --dport 8787 -j to the end of the file. While I was editing the file, I also added /sbin/iptables -I INPUT -p tcp --dport 4321 -j to open up the port for Hugo. I’m switching to blogdown for my website and wanted to be able to easily get at the preview versions.

update 2018-01-30: Actually forgot to do this with my test of the xfce desktop and I had no trouble access the server. So, apparently not needed. I’m keep the instructions here mostly so I have access to them if other things (i.e. hugo) do require them.

Get RStudio server running and access it

Now you need to start up the server.

sudo rstudio-server start

Then in your browser you can access your RStudio Server with localhost:8787

Draw the rest of f***ing owl

Apologies if you have seen the “how to draw an owl” meme. It feels appropriate at this point. What follows are all the things I had to add to get up and running with my standard set-up.

First, let’s change the locale and add some needed tools

sudo locale-gen "en_US.UTF-8"
sudo dpkg-reconfigure locales
sudo apt-get install software-properties-common libxslt1-dev libcurl4-openssl-dev libssl-dev libssh2-1-dev

Next I needed to add the Ubuntu GIS repositories so I can get the up to date versions of GDAL, GEOS, etc.

sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable
sudo apt-get update

And add my GISy libraries

sudo apt-get install libgdal-dev libproj-dev libudunits2-dev

Then we can add LaTeX

sudo apt-get install texlive texlive-latex-extra texlive-pictures

In my experience this is close to the minimal LaTeX install that will work with pandoc, R Markdown, etc.

Lastly, some version control!

sudo apt-get install git

And then I configure git.

git config --global user.name "Your Name"
git config --global user.email "[email protected]"
git config --global credential.helper 'cache --timeout=28800'

Day to day use

There is a way to have your chroot automatically boot with Chrome OS and RStudio Server is supposed to start on boot. For some reason, the server wasn’t kicking off when I started up the chroot. I didn’t track this down so don’t know if it will work. Seems like with some hacking it should.

So given that I couldn’t get everything starting automagicaly, the simplest solution I came up with is to:

  • start up my chromebook
  • open crosh - ctrl-alt-t
  • type shell
  • type sudo enter-chroot
  • type sudo rstudio-server start
  • type localhost:8787 into a broswer tab.

Another way to go with this is set up a couple of aliases in ~/.bashrc. You can do this with:

  • at your crosh shell: vi ~/.bashrc
  • add this to the file: alias rstudio="sudo enter-chroot -n rstudio"
  • now type in the shell . ~/.bashrc.
  • type rstudio in the shell. Once you enter your password, you will be in your chroot.
  • enter some aliases for starting the server
  • type nano ~./bashrc
  • add this: alias rstudio="sudo rstudio-server start"
  • type rstudio, enter password.
  • type localhost:8787 into a browser tab.

The first time I get RStudio open I want to install all my usual suspects. With this set up I had no issues installing the following

pkgs <- c("devtools","tidyverse","sf","raster","mapview","sp","rgdal","rgeos","roxygen2", "blogdown")

lapply(pkgs, install.packages)

I then install my own packages, just so I have them handy

One little hiccup

The shutdown process is not super smooth on this (only problem I have identified so far). When your chromebook sleeps, or you shut down the chroot, etc. The R session and RStudio get confused. A scary error will pop-up when you try to get backin in and at this point, I can no longer switch between projects. When you select a new project it looks like it is switching, but ends keeping you at your root without a project. If you don’t use projects then this might not be an issue (but you do risk the arsonistic ire of Jenny Bryan). If you do use projects this is a problem. I did find a very simple workaround for when this happens. All you need to do is start a new session. This can be done with the little red power button icon in the upper right corner of the window or with Session.

update 2018-01-30: Using the xfce desktop install seems to have fixed this issue. No need to unnecessarily start new session now!

So, there you have it. RStudio on a chromebook via RStudio Server running in a chroot! I am now very happy with the set-up and fully expect to stick with the Chromebook for some time to come.

Setting up an Asus Flip C302CA Chromebook for R Development

Don’t think of this as a real blog post. It is mostly a loose collection of notes that I took while getting my new Asus Flip C302CA set up with R and RStudio. I’ve had this up and running for just a few days now (and in fact wrote this post using RStudio on it) and I love it. I highly recommend.

The steps below are not really tested. So if you run into problems or I have missed something, let me know.

Steps

  1. Enter Developer Mode
    • Esc - Refresh - Power
    • Follow directions
    • Takes a while (~30 minutes)
  2. Download crouton
  3. Add crouton integration extension
  4. Create chroot
    • Open crosh - ctrl-alt-T
    • Start bash - shell
    • Intall xfce xiwi extension touch
    • sudo sh ~/Downloads/crouton -e -t xfce,touch,xiwi,extension - It’ll ask for a new username and password - Since we are encrypting the chroot (with -e) it will also ask for a passphrase. I’m certainly not a security expert, but don’t use the same one as your google or new chroot password… - This takes a while (~15 minutes)
  5. You should now have a working ubuntu install with the xfce desktop available. Fire that up.
    • If you don’t have shell still open, get to that (ctrl-alt-T and shell)
    • type sudo startxfce4
    • Ta-da! Linux!
  6. Now we can start installing all the tools that we need from our xfce window.
    • get to a terminal
    • Install Git
sudo echo "deb http://cran.rstudio.com/bin/linux/ubuntu xenial/" | sudo tee -a /etc/apt/sources.list
gpg --keyserver keyserver.ubuntu.com --recv-key E084DAB9
gpg -a --export E084DAB9 | sudo apt-key add -
sudo apt-get update
sudo apt-get install r-base r-base-dev
  • Install RStudio
    • I like to live on the edge so I usually have a fairly recent daily running. Here’s how you get that.
    • You will also need to add some older versions of libgstreamer. Good details on this from Mike Williamson.
    • I also delete the .deb since this is on a chromebook. Space will likely be at a bit of a premium.
# Download the installs
wget https://s3.amazonaws.com/rstudio-dailybuilds/rstudio-1.1.244-amd64.deb
wget http://ftp.ca.debian.org/debian/pool/main/g/gstreamer0.10/libgstreamer0.10-0_0.10.36-1.5_amd64.deb
wget http://ftp.ca.debian.org/debian/pool/main/g/gst-plugins-base0.10/libgstreamer-plugins-base0.10-0_0.10.36-2_amd64.deb
 
# Now install deps with dpkg and mark to not update
sudo dpkg -i libgstreamer0.10-0_0.10.36-1.5_amd64.deb
sudo dpkg -i libgstreamer-plugins-base0.10-0_0.10.36-2_amd64.deb
sudo apt-mark hold libgstreamer-plugins-base0.10-0
sudo apt-mark hold libgstreamer0.10

# Lastly install rstudio
sudo gdebi rstudio-1.1.244-amd64.deb
rm rstudio-1.1.201-amd64.deb
  • The following are the notes I had for which libraries I added. My notes were a bit of a mess so this might not be all or may be too many.

Some of the basics (i.e. for devtools)

sudo apt-get install libxslt-dev libcurl4-openssl-dev libssl-dev

The spatial stuff. This also adds the ubuntugis repo so that you can get the latest and greatest. The latest is at https://launchpad.net/~ubuntugis/+archive/ubuntu/ubuntugis-unstable

But, add-apt-repository was not installed. To get that I used sudo apt-get install software-properties-common. Now to add the GIS stuff.

sudo add-apt-repository ppa:ubuntugis/ubuntugis-unstable
sudo apt-get update
sudo apt-get install libgdal-dev libproj-dev

In addition to gdal, geos, and proj, libudunits2-dev is needed and can be installed with apt-get: sudo apt-get install libudunits2-dev.

Also, if you do any work with rmarkdown, knitr, and the like you will probably want a working install of latex. I used the following:

sudo apt-get install texlive texlive-latex-extras texlive-pictures
  1. Working with RStudio on your chromebook

Not a whole lot of details here. Just some basic notes I had for myslef. First, I am using a 64GB microSD card to give myself some room and I keep all of my projects stored on this card (as well as on GitHub). I just set up a symbolic link to this from my home folder. Something like the following should do the trick.

cd 
ln -s /var/host/media/removable/SD\ Card/ projects

With this you can get to the card easier (e.g. cd ~/projects). Only issue I have had with this is that trying to browse local HTML files from R blows up as the linux path to the SD Card doesn’t play nice on the Chrome OS side. Still need to figure this one out.

I am still playing around with the best way to fire up rstudio. There are two ways I am doing this. Either firing up a separate desktop and using RStudio from there or starting RStudio in its own window. I think I prefer the later, but time will tell. You already know how to fire up the desktop. You can use rstudio from a terminal or find it in your applications menu. For the RStudio in its own window, I added this:

alias rstudio="sudo startxiwi rstudio -F"

to my ~/.bashrc in the chromebook (not the chroot!) shell. Then I can fire up rstudio with ctrl-alt-T, then shell, then rstudio.

Given the hi-res of the screen, you’ll need to either get super vision or mess with the display settings in the Xfce desktop or adjust the X11 setting that the Chrome crouton integration is using. I used a lot of the suggestions in the crouton on Pixel section of the crouton Wiki. In particular, Option 1 helped with firing up RStudio direction. I also bumped the zoom in my RStudio Global options.

Lastly, the locale is not set in your linux install so to take care of that, I followed these directions from Ask Ubuntu. In particular:

sudo locale-gen "en_US.UTF-8"
sudo dpkg-reconfigure locales #you'll need to cycle through with arrows, tabs, and enters

I think that should do the trick on any locale issues, but dealing with this made me realize how little I actually now about locales and text encoding…

Fnally and hopefully you should now be ready to roll with R and R development on your fancy new chromebook! See below for some additional links.

Some related links

Spatial Data Analysis in R: Lightning Demo!

At this years NEARC meeting I decided to give a lightning talk on using R as a GIS. As I was working on this I thought, “why not try a lightning demo?” That would be better than five minutes of slides on packages and commands. But, as anyone who has done a live demo will know, they often provide unexpected challenges. Add a 5 minute limit to that, and well, some level of failure is sure to occur. Becuase of this I have decided put everything into a web page so that the attendees (and others) can access the full demo at a later date. The full text and code is at http://jwhollister.com/rgis_lightning_demo.

I finally got quickmapr on CRAN!

A little over 7 months ago I posted about a package that I had been working on, quickmapr. That was the pre-release version, the one that I finished up today and submitted to CRAN is a bit more polished, plots rasters a bit quicker, and is, I think, ready for wider release. It is now availble from CRAN.

The README on GitHub provides details plus some examples using a small dataset included with the package. I would be thrilled to get some feedback from people on the package, ease of use, suggestions for improvements, etc. I would be even more thrilled if you try it out on different datasets. Any thoughts just add them as issues.

Download Shapefiles - Take 2

So back in 2013 I posted a little function I wrote for grabbing all the relevant files that make up a shapefile from a URL. Turns out it doesn’t play so well with Windows 7 or Windows 8 (HT: John Lewis). Below is a reprised version that at least works on Ubuntu 14.04 and Windows 7. Haven’t tested it beyond that and supressing the warnings to get httr::GET to not complain too much about FTP seems a bit unclean. Well, you get what you pay for.

For all this to run you’ll need RCurl, httr, sp, and rgdal.

download_shp<-function (shape_url, layer, outfolder = ".") 
{
  if (length(grep("/$", shape_url)) == 0) {
    shape_url <- paste(shape_url, "/", sep = "")
  }
  
  shapefile_ext <- c(".shp", ".shx", ".dbf", ".prj", ".sbn", 
                     ".sbx", ".shp.xml", ".fbn", ".fbx", ".ain", ".aih", ".ixs", 
                     ".mxs", ".atx", ".cpg")

  xlogic <- NULL
  if(substr(shape_url,1,3)=="ftp"){
    xurl <- RCurl::getURL(shape_url)
    for (i in paste(layer, shapefile_ext, sep = "")) {
      xlogic <- c(xlogic, grepl(i, xurl))
    }
  } else if(substr(shape_url,1,4)=="http"){
    for (i in paste(shape_url,layer, shapefile_ext, sep = "")) {
      xlogic <- c(xlogic,httr::HEAD(i)$status==200)
    }  
  }
  
 
  shapefiles <- paste(shape_url, layer, shapefile_ext, 
                      sep = "")[xlogic]
  outfiles <- paste(outfolder, "/", layer, shapefile_ext, 
                    sep = "")[xlogic]
  
  if (sum(xlogic) > 0) {
    for (i in 1:length(shapefiles)) {
      x <- suppressWarnings(httr::GET(shapefiles[i], 
                                      httr::write_disk(outfiles[i],
                                                       overwrite = TRUE)))
      
      dwnld_file <- strsplit(shapefiles[i], "/")[[1]]
      dwnld_file <- dwnld_file[length(dwnld_file)]
      
      print(paste0("Downloaded ", dwnld_file, " to ", 
                   outfiles[i], "."))
    }
  }
  else {
    stop("An Error has occured with the input URL or 
              name of shapefile")
  }
}

And to see that it works again:

#Download the NH State Boundaries
download_shp("ftp://ftp.granit.sr.unh.edu/pub/GRANIT_Data/Vector_Data/Administrative_and_Political_Boundaries/d-nhsenatedists/2012",
                   "NHSenateDists2012")
## [1] "Downloaded NHSenateDists2012.shp to ./NHSenateDists2012.shp."
## [1] "Downloaded NHSenateDists2012.shx to ./NHSenateDists2012.shx."
## [1] "Downloaded NHSenateDists2012.dbf to ./NHSenateDists2012.dbf."
## [1] "Downloaded NHSenateDists2012.prj to ./NHSenateDists2012.prj."
## [1] "Downloaded NHSenateDists2012.sbn to ./NHSenateDists2012.sbn."
## [1] "Downloaded NHSenateDists2012.sbx to ./NHSenateDists2012.sbx."
#Read shapefiles in SpatialPolygonsDataFrame
NHBnd<-readOGR(".","NHSenateDists2012")
## OGR data source with driver: ESRI Shapefile 
## Source: ".", layer: "NHSenateDists2012"
## with 24 features
#Plot it
plot(NHBnd)

plot of chunk run_it