R Programming Language 📍

R is a programming language and free software environment for statistical computing and graphics supported by the R Core Team and the R Foundation for Statistical Computing. It is widely used among statisticians and data miners for developing statistical software and data analysis.

📽️ Videos

Scraping SeeThroughNY Data using R

Here is the R code I am using to scrape SeeThroughNY.net to download state and local government employment wage data.

library(tidyverse)
library(RSelenium)
library(netstat)
library(rvest)

# Load Selenium browser. This code should automatically open a Firefox window
# from r, downloading the latest GeckoDriver if neccessary.
#
# If this doesn't work, you should delete the LICENSE.chromedriver which
# sometimes causes rSelenium to not load.
## find ~/.local/share/ -name LICENSE.chromedriver | xargs -r rm

rs <- rsDriver(
  remoteServerAddr = "localhost",
  port = free_port(random = T),
  browser = "firefox",
  verbose = F
)

rsc <- rs$client
rsc$navigate("https://seethroughny.net/payrolls")

# STOP !!!
# While you could automate this step, you should now manually choose your 
# search items on SeeThroughNY browser window that has opened. Then 
# you should execute the following lines.

# Next you want to load all of the results. We limit it to 30 attempts,
# which will pull most reasonably sized queries. Too big and you could crash
# your browser due to excessive memory needed.

for (i in seq(1,30)) {
  rsc$findElement(using='css', '#data_loader')$clickElement()
  
  if (rsc$findElement(using='css', '#data_loader')$getElementAttribute('style')[[1]] == 'display: none;')
    break;
 
  Sys.sleep(2)
}

# Next you need to pull and clean the HTML table that
# contains the data
rsc$getPageSource() %>%
  unlist() %>%
  read_html() %>%
  html_table() %>%
  .[[1]] %>% 
  janitor::clean_names() -> employees

# Some of the data is located in the (+) tab, but this is just a
# table field located every other row, which split up into the appropiate
# field values

employees %>%
  filter(row_number() %% 2 == 0) %>%
  select(name) %>%
  separate(name, sep='\n', into=c(NA,'subagency',NA,NA,NA,'title',NA,NA,NA,'rateofpay',NA,NA,NA,'payyear',NA,NA,NA,'paybasis',NA,NA,NA,'branch') ) %>%
  cbind(employees %>% filter(row_number() %% 2 != 0), .) %>%
  mutate(across(everything(), str_trim),
         total_pay = parse_number(total_pay)) %>%
  select(-x, -x_2, -subagency_type) -> employees

### Then you can pipe this data into ggplot or any other program.
### Or export it to CSV or Excel file
employees %>% write_csv('/tmp/employee_data.csv')

R 4.30 Was Released

With R 4.3.0 released on Friday, you can now use an “underscore” with the built-in pipe, like you could use a “period” in maggittr pipe. While there are still some reasons to use maggittr, like T-pipes, assignment pipes and exposition pipes, I’ve never used them and they aren’t exported by default in the tidyverse.

For example, in maggittr you could do:

df %>% inner_join(states, .)

And now with the native pipe you can do the same thing:

df |> inner_join(states, _)

That was a major oversight when the created the native pipe, I’m not sure why it wasn’t originally implemented when 4.0.0 came out but it wasn’t.

Also, you can use _$value to extract something from R:

mtcars |> lm(mpg ~ disp, data = _) |> _$coef

Although, I’m not totally sure why you want to use a pipe like that when you can put the extractor directly on the lm:

mtcars |> lm(mpg ~ disp, data = _)$coef

Learn more about the changes in R 4.30: https://www.jumpingrivers.com/blog/whats-new-r43/

Get R version 4.3.0 (Already Tomorrow) which was released on 2023-04-21.

And here is the full list of changes in R 4.30.

I often think about all the interesting — and time saving things — I’ve learned in R over the past year and a half

I often think about all the interesting — and time saving things — I’ve learned in R over the past year and a half. On Election Night, I wrote a script that used a headless Firefox browser and Selenium to pull Election Results in real-time and process it into an a Google Spreadsheet. I was pleasantly surprised how well it worked, and how with a few extra lines of code I could pipe it into ggplot and make all kinds of maps.

The New York City Gubernatorial maps I posted where much the same way. I took data from several NYC Election Night Results pages, aggregated it into a data frame, cleaned up and formatted the data, then piped it through to ggplot with some nice styling.

Every day, I try to learn and experiment in new directions, build my skills further. As I only become faster and more talented at using R the more I use it and learn the many shortcuts and libraries out there for writing better code, quicker.