Monday, 6 September 2010

Less than negative?

An interesting thing that I found while doing the analysis for my previous post on the Canterbury earthquakes, was the difficulty of constraining figures less than a negative number. For example:

a<-seq(1, 10, 1)
b<-a[a>3 & a<7]
c<-seq(-1, -10, -1)
d<-c[c<-3 & c>-7]

> a
[1] 1 2 3 4 5 6 7 8 9 10
> b
[1] 4 5 6
> c
> d
[1] -1 -2 -3 -4 -5 -6

The boolean operator for selecting a range less than a negative number ends up being the same as the assignment operator. To get around this I simply define the function neg()

neg<-function(x) -x
c<-seq(-1, -10, -1)
d<-c[c<neg(3) & c>neg(7)]

> c
[1] -1 -2 -3 -4 -5 -6 -7 -8 -9 -10
> d
[1] -4 -5 -6


Albert said...

Why don't you just use:

cc[c< -3 & c> -7]

The space is sufficient to allow a correct parsing of the expression.

Samuel Brown said...

I didn't know that. Thank you Albert!

Christian said...

This is a problem I often ask my students to solve!

Efrique said...

Since you presumably already know that "c<-3" is going to be an assignment, the thing that should worry you is how the compiler is supposed to figure out when you mean something else.

The obvious idea is to use parentheses "c<(-3)" if you aren't sure whether "c< -3" is enough (which it is).

I usually try to use spaces to make the intent clear to a human reader (usually me), and the interpreter is fortunately clever enough to follow along:

c <- 3 for assignment
c < -3 for the test

(I experience some trepidation at using c for anything but the function c(), as well. The chances that I'll end up doing something dumb but hard to spot after that would be high)

-ricardo said...

I know I'm two years late to the conversation, but something someone taught me might help here: Always put the unassignable value on the left hand side of the inequality. This way you never accidentally reassign a variable. Plus it helps track down bugs were you forgot a double equals, which is used in many, but not all, languages.