[R] The end of Matlab

Claudia Beleites cbeleites at units.it
Fri Dec 12 15:05:29 CET 2008

Am Freitag 12 Dezember 2008 13:10:20 schrieb Patrick Burns:
> How about:
> x[, -seq(to=ncol(x), length=n)]
Doing it is not my problem. I just agree with Mike in that I would like if I 
could do shorter than: 

x[, 1 : (ncol(x) - n)] 

which I btw prefer to your solution.

Also, I don't have a problem writing generalized versions of head and tail to 
work along other/more dimensions. Or a combined function, taking first and last 

Still, they would not be as convenient to use as matlab's:
3 : end - 4
which btw. also does not need parentheses.

I guess the general problem is that there is only one thing with integers that 
can easily be (ab)used as a flag: the negative sign. 

But there are (at least) 2 possibly useful special ways of indexing: 
- exclusion (as in R)
- using -n for end - n (as in perl)

Now we enjoy having a shortcut for exclusion (at least I do), but still feel 
that marking "from the end" would be useful.

As no other signs (in the sense of flag) are available for integers, we won't 
be able to stop typing somewhat more in R.

> x[3:]
> instead of
> x[3:length(x)]
> x[3:end]
I don't think that would help: 
what to use for end - 3 within the convention that negative values mean 

--- now I start "dreaming" ---

However, it is possible to define new binary operators (operators are great for 
lazy typing...).

Let's say %:% should be a new operator to generate proper indexing sequences 
to be used inside "[" :
e.g. an.array [ 1:3, -2 %:% -5, ...]

If we now find an.array which is x inside "[" (and also inside "[[") - which is 
possible but maybe a bit fiddly

and if we can also find out which of the indices is actually evaluated (which I 
don't know how to do)

then we could use something* as a flag for "from the end" and calculate the 
proper sequence.

something* could e.g. be 
either an attribute to the operators (convenient if we can define an unary 
operator that allows setting it, e.g. § 3 [§ is the easy-to-type sign on my 
keyboard that is not yet used...])

or i (the imaginary one) if there is no other convenient unary operator e.g. 

easy part of the solution:
make.index <- function (x, along.dim = 1, from, to){
	if (is.null (dim (x)))
	   dim <- length (x)
	  dim <- dim (x)[along.dim]

	if (is.complex (from)){
		from <- dim - from # 0i means end
		## warning if re (from) != 0 ?
	if (is.complex (to)){
		to <- dim - to # 0i means end
		## warning if re (to) != 0 ?
	from : to

"%:%" <- function (e1, e2)  ## using a new operator does not mess up ":"
	make.index (x = find.x (), along.dim = find.dim (), e1, e2)

now, the heavy part are the still missing find.x () and find.dim () functions...

I'm not sure whether this would be worth the work, but maybe someone is around 
who just knows how to do this.


Claudia Beleites
Dipartimento dei Materiali e delle Risorse Naturali
Università degli Studi di Trieste
Via Alfonso Valerio 6/a
I-34127 Trieste

phone: +39 (0 40) 5 58-34 47
email: cbeleites at units.it

More information about the R-help mailing list