Corresponding

May 7, 2011
By

(This article was first published on Struggling Through Problems, and kindly contributed to R-bloggers)

(The examples here work with the version of insidefunctor tagged as "v2")

Unfortunately I couldn't do this cleanly outside the library. So the changes are made in insidefunctor.

Levels are no longer used to "line up" eaches. So, for example,

> library(insidefunctor)

> `%+.%` = fmap(`+`)

> `%/.%` = fmap(`/`)

> x = c(1, 2, 3)

> y = c(4, 5, 6)

> .[z] = each(x) %+.% each(y)

> z


  • 5  6  7

  • 6  7  8

  • 7  8  9



> .[w] = each(x) %+.% pond(y)

> w

5  7  9

where "pond" stands for "corresponding" and is chosen because no one would use the word pond for anything else.

But this is so much more flexible! Because the definition of "corresponding" is itself flexible. Here it means "having the same sequential position", but it could be taken to mean just about anything else. Like, for example, a linearly-interpolated lookup-table:

> `%near%` = function(y, x) {

> UseMethod("%near%")

> }

> looktable = function(dep, ind) {

> reorder = order(ind)

> dep = dep[reorder]

> ind = ind[reorder]

> attr(dep, "indvar") = ind

> class(dep) = c("looktable", class(dep))

> dep

> }

> `%near%.looktable` = function(y, x) {

> pond(approx(attr(y, "indvar"), y, x)$y)

> }

All it does is translate linear nearness into sequential correspondence, ie exactly what approx() does in the first place. Then you can use it like

> .[u] = each(1:5) %+.% reeval(runif(1))

> u

1.29927378566936  2.63695163559169  3.90192435029894  4.71558610373177  5.38200953858905

> v = looktable((0:6)^2, 0:6)

> v

0  1  4  9  16  25  36

> .[w] = v %near% u

> w

1.89782135700807  7.18475817795843  15.3134704520926  22.4402749335859  29.2021049244795

> .[z] = (v %near% u) %/.% each(u)

> z

1.46067855592911  2.72464541290166  3.92459439940689  4.75874566595812  5.42587387017808

These could of course have been done just as easily in straight-up R. The only difference is grammar. You can generalize corresponding to other kindns of lookups, like, say, functions:

This is a little trickier because if you were to say

> each(u) %/.% the(sin)

when the(sin) is called it has no idea what axis it runs along, ie it can't sequentially correspond at that time. Luckily the definition of correspondence is flexibly: it is done through several generic functions:

> corresponds = function(arg, inside) {

> UseMethod("corresponds")

> }

> alignable = function(arg, inside) {

> UseMethod("alignable")

> }

> corresponding = function(arg, inside, i) {

> UseMethod("corresponding")

> }

With defaults suitable for sequential correspondence:

> corresponds.correspondence = function(arg, inside) {

> if (is.null(arg$ref)) {

> T

> }

> else {

> identical(arg$axis, inside$axis)

> }

> }

> alignable.correspondence = function(arg, inside) {

> identical(arg$axis, inside$axis)

> }

> corresponding.each = function(arg, inside, i) {

> part = arg$items[[i]]

> arg$items[[i]]

> }

So all we need to do is provide methods to tell apply.functor.each that the(sin) corresponds to each(u), that they are alignable, and, given an element of u, to find the corresponding element in the(sin).

> the = function(func) {

> the = list(

> func = func

> )

> class(the) = c('the', class(the))

> the

> }

> corresponds.the = function(the, inside) {

> T

> }

> alignable.the = function(the, inside) {

> T

> }

> corresponding.the = function(the, inside, i) {

> the$func(inside$items[[i]])

> }

Now see if that works:

> u = c(1, 2, 3)

> u

1  2  3

> .[v] = each(u) %/.% the(sin)

> v

1.18839510577812  2.19950034058923  21.2585021872116

Alas we still could not do

> plot(each(seq(0, 1, len = 100)), the(sin))

because the elements would not be collected at the time of calling plot(). Perhaps another functor could fix this.

To leave a comment for the author, please follow the link and comment on his blog: Struggling Through Problems.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...



If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Comments are closed.