examples/5_classification/example_4.R

# Example 4. Get familiar with the common visual tasks in JS (p5.js) and
# leverage R's modelling ability (KNN classification). This app is inspired by
# http://cs.stanford.edu/people/karpathy/convnetjs/demo/classify2d.html
rm(list = ls())
library(jsReact)
library(magrittr)
my_html <- create_html() %>%
  add_js_library("p5") %>%
  add_column(id = "column_1", align = 'center') %>%
  add_column(id = "column_2", align = 'center', into = "column_1") %>%
    add_text("<b>KNN classification</b><br>", into = "column_2") %>%
    add_text("Click to create red dots. <br> Click with key pressed to create green dots.",
           into = "column_2")
my_html %<>% add_script(
" var data0 = {'x1': [], 'x2': [], 'y': []};
  var grid_data = {'x1': [], 'x2': [], 'y': []};
  ws.onmessage = function(msg) {
    grid_data = JSON.parse(msg.data);
  }
  var canvas_width = 400;
  var canvas_height = 400;
  function setup() {
    var my_canvas = createCanvas(canvas_width, canvas_height);
    my_canvas.parent('column_1');
    rect(0, 0, canvas_width-1, canvas_height-1);
  }
  function draw() {
    plot_data(grid_data, 'bg');
    plot_data(data0, 'data');
  }
  function plot_data(data0, type) {
    console.log(data0['x1']);
    var n = data0['x1'].length;
    for (var i = 0; i < n; i++) {
      if (data0['y'][i] == 1) {
        fill(0, 255, 0);
      } else {
        fill(255, 0, 0);
      }
      if (type == 'bg') {
        rect(data0['x1'][i], data0['x2'][i], 20, 20);
      } else {
        ellipse(data0['x1'][i], data0['x2'][i], 10, 10);
      }
    }
  }
  function mouseClicked() {
    data0['x1'].push(mouseX);
    data0['x2'].push(mouseY);
    if (keyIsPressed === true) {
      data0['y'].push(1);
    } else {
      data0['y'].push(0);
    }
    ws.send(JSON.stringify(data0));
  }
")


my_r_fun <- function(in_msg) {
  grid_data <- make_uniform_grid(0, 400, 20)  # this is a 'constant' df. Inefficient but easy to do.
  train_data <- data.frame(x1 = in_msg$x1, x2 = in_msg$x2, y = in_msg$y)
  # Refit models
  knn_pred <- class::knn(
    train = train_data[,1:2], test = grid_data[,1:2], cl = train_data[,3]
  )
  grid_data[['y']] <- as.numeric(as.character(knn_pred))
  as.list(grid_data)
}
# Helpers
make_uniform_grid <- function(min0, max0, resolution = 100) {
  one_side_grid <- seq(min0, max0, length.out = resolution)
  grid_data <- expand.grid(one_side_grid, one_side_grid)
  grid_data <- data.frame(grid_data, 0)
  names(grid_data) <- c('x1', 'x2', 'y')
  grid_data
}

preview_app(my_html, my_r_fun, T)
kcf-jackson/jsReact documentation built on May 29, 2019, 3:01 a.m.