Basic conversion from R to JavaScript

The package currently has 188 AST rewriting rules. Here are a list of the basic ones.

Description R JavaScript
Assignment of variable x <- 1 x = 1
Access object attribute obj$x obj.x
Vector (JS Array) c(1, 2, 3, 4, 5) [1, 2, 3, 4, 5]
List (JS Object) list(x = 1, y = 2) {x:1, y:2}
Conditionals if (cond) {...}
else if (cond) {...}
else {...}
if (cond) {...}
else if (cond) {...}
else {...}
For-loop for (x in iterable) {...} for (let x of iterable) {...}
While-loop while (cond) {...} while (cond) {...}

Note that the conversion is not perfect, e.g. 

  • R vector cannot be nested, while JS array can be nested.

    • c(1, 2, c(3,4), 5) is the same as c(1, 2, 3, 4, 5), but
    • [1, 2, [3, 4], 5] is not the same as [1, 2, 3, 4, 5].
  • R list can be unnamed, but JS object must be fully named.

    • But don’t worry, when you try to convert an R unnamed list to JS object, sketch will warn you about it :)

Supported R functions

Groups Functions
Vector c, extract, extractAssign, rep, seq
Matrix matrix, extract, extractAssign
List list, extract, extractAssign, extract2, extract2Assign, names, append
Dataframe data.frame, extract, extract2, extractAssign, mutate, filter, select, arrange
Binary operators add, subtract, multiply, divide, pow, mod, intDivide
Comparison operators all_equal, EQ, LT, GT, NEQ, LEQ, GEQ
Logical operators and, or, xor, not
Math functions pi, abs, sign, sqrt, floor, ceiling, trunc, round, signif, cummax, cummin, cumprod, cumsum, exp, log, expm1, log1p, gamma, lgamma, digamma, trigamma, log10, log2, factorial, choose, lchoose
Trigonometry functions cos, sin, tan, cospi, sinpi, tanpi, acos, asin, atan, cosh, sinh, tanh, acosh, asinh, atanh
Summary and statistics mean, median, sd, sd2, quantile, max, min, range, prod, sum, all, any
Set functions setdiff, unique, intersect, is_element, is_subset, length, union
Complex functions complex, Re, Im, Mod, Arg, Conj
Sampling functions Uniform, Normal, Gamma, Exponential, Chi-squared, Lognormal, Poisson, Geometric, Binomial, Bernoulli
Higher-order functions Map, Filter, Reduce
Extra erf, cot, acot, coth, acoth, csc, acsc, csch, acsch, sec, asec, sech, asech, setsymdiff

R-like data structure and processing

Vector, Matrix and Array

Vector

# Vector
x <- 1:10
y <- 11:20
print(x[0])     # JavaScript uses 0-based indexing
print(x + 1)    # Supports vector-scalar arithmetic
print(x + y)    # Supports vector-vector arithmetic

z <- x          # Supports passing object by *value*
x[0] <- 999
print(x)
print(z)

Matrix

# Matrix
x <- matrix(1:10, 2, 5)
y <- matrix(11:20, 2, 5)

print(x[0,0])   # JavaScript uses 0-based indexing
print(x[0, ])   # First row
print(x[, 0])   # First column

print(x + 1)    # Supports matrix-scalar arithmetic
print(x + y)    # Supports matrix-matrix arithmetic

Array

# Array
x <- array(1:24, c(2,3,4))
y <- array(25:48, c(2,3,4))
print(x[0, 0, 0])  # JavaScript uses 0-based indexing
print(x[0, 0, ])
print(x[0, , ])

print(x + 1)    # Supports array-scalar arithmetic
print(x + y)    # Supports array-array arithmetic

List

# List
list_1 <- list(x = 1, y = 2)
print(names(list_1))
print(list_1$x)        # Supports dollar notation
print(list_1[0])       # Supports extract
print(list_1[[0]])     # Supports extract2

Dataframe

At the moment, sketch uses dataframe.js for the back-end for the data frame, and there are some differences to the data frame used in R.

df0 <- data.frame(
    x = c(1, 4, 2, 2), 
    y = c(6, 2, 10, 5), 
    z = c(3, 4, 4, 10)
)

print("\n===== Mutate double_x and double_y ==============================")
double_x_fun <- function(row) { return(2 * row$get("x")) }
double_y_fun <- function(row) { return(2 * row$get("y")) }
df0 %>%
    mutate("double_x" = double_x_fun, 
           "double_y" = double_y_fun) %>%
    print()

print("\n===== Select only x and y ======================================")
df0 %>% 
    select("x", "y") %>% 
    print()

print("\n===== Filter x >= 2 ============================================")
greater_than_two <- function(row) { return(row$get("x") >= 2) }
df0 %>% 
    filter(greater_than_two) %>% 
    print()

print("\n===== Arrange by x, then by y ==================================")
df0 %>% 
    arrange(c("x", "y")) %>% 
    print()