# plot points that fall within an interest area

#### maziana

##### New Member
I want to find which points fall within an interest area, and then plot only those points. Here is a basic example.

Code:
install.packages("sp") #install package that allows usage of point in polygon
library(sp)

x <-1:10
y <- 1:10

#polygon is plotted as (1,1) (6,1) (6,5) (1,5)
inIA <- point.in.polygon(x,y,c(1,6,6,1),c(1,1,5,5))

inIA
[1] 3 1 1 1 2 0 0 0 0 0

#inIA reports which points fall within the polygon - the first 5 points
Now what I want to do is plot the points that correspond to inIA's values that are greater than 0. In this example, it would be easy to plot them manually since it is the first five points (plot(1:5,1:5)), but my actual code uses points and polygons that are more complex.

For example, inIA might equal 0 0 1 0 0 1 1 1 0 1 1 and I would want to plot the third point, sixth, seventh, etc. The points are predefined in a database and numbered by order (n):

n x y
1 5 6
2 3 4
3 8 1
4 8 2
...

All the ways I tried to do this were clearly wrong, because I keep getting the message "the condition has length > 1 and only the first element will be used" when I try plotting from inIA. But I want to treat each value in inIA separately. I'm fairly new to R, so I would appreciate any help.

#### Dason

So you just want to find which values are greater than 0?

Code:
dat <- cbind(x,y)
points.to.plot <- dat[inIA > 0,]

#### maziana

##### New Member
Thank you; that worked. I do have another question though. Not only did I want to plot the points greater than 0, but I also wanted to plot points in a different way:

I wanted to plot the points where there are two or more in a row that are greater than 0. For example, if I had 0100111011001, then I would not plot the second point and the last point, since they are surrounded by 0s. I would plot the other five 1s, though, since each has a 1 on at least one side.

Does anyone have any ideas?

#### maziana

##### New Member
Code:
x <- c(0,1,8,3,4,10,5,2,5,1,3)
y <- c(0,2,8,4,3,1,4,4,5,0,3)
inIA <- point.in.polygon(x,y,c(1,6,6,1),c(1,1,5,5))
inIA
[1] 0 2 0 1 1 0 1 1 2 0 1
I want points.to.plot to only include the 4th, 5th, 7th, 8th, and 9th points. Not the 2nd and 11th points, since they are not after or followed by any points within the interest area.

#### maziana

##### New Member
I'm gonna bump this thread to say I'm still interested in any potential solutions to my above post. Even a nudge in the right direction would be helpful. Is R capable of selecting only grouped points (two or more in a row) from a vector while keeping the code minimally complicated? Thanks.

#### Dason

So you only really care about values greater than 0 right? The beginning is the internals of the function I wrote but it's easier to follow along and examine the output of each step that way...

Code:
x <- c(0, 2, 0, 1, 1, 0, 1, 1, 2, 0, 1)

# Only really care about detecting if > 0
out <- rle(x > 0)
# figure out whichs ones are greater than 0
trues <- which(out$values) # Get the lengths of the run lengths tmp <- out$lengths[trues]
# If it was by itself change the value to a FALSE
out$values[tmp == 1] <- FALSE # expand back and figure out which values are still TRUE which(inverse.rle(out)) myfinder <- function(x){ out <- rle(x > 0) trues <- which(out$values)
tmp <- out$lengths[trues] out$values[tmp == 1] <- FALSE
which(inverse.rle(out))
}

myfinder(x)
Does that do what you want?

#### maziana

##### New Member
I really appreciate you laying the code out like that. However, at a first glance, it doesn't look like it retrieves the right points.

Code:
x <- c(0,1,8,3,4,10,5,2,5,1,3)
y <- c(0,2,8,4,3,1,4,4,5,0,3)
inIA <- point.in.polygon(x,y,c(1,6,6,1),c(1,1,5,5))

inIA
[1] 0 2 0 1 1 0 1 1 2 0 1

myfinder <- function(x){
out <- rle(x > 0)
trues <- which(out$values) tmp <- out$lengths[trues]
out$values[tmp == 1] <- FALSE which(inverse.rle(out)) } myfinder(inIA) [1] 2 7 8 9 myfinder returns only 4 points, and it should return 5 (numbers 4, 5, 7, 8, and 9). I don't have time right now, but I will later take a closer look at the code to see why, and see how to plot the points that myfinder returns... #### Dason ##### Ambassador to the humans Oops. I made a modification earlier but I guess I posted the wrong version. Code: x <- c(0, 2, 0, 1, 1, 0, 1, 1, 2, 0, 1) # Only really care about detecting if > 0 out <- rle(x > 0) # figure out whichs ones are greater than 0 trues <- which(out$values)
# Get the lengths of the run lengths
tmp <- out$lengths[trues] # If it was by itself change the value to a FALSE out$values[trues[tmp == 1]] <- FALSE
# expand back and figure out which values are still TRUE
which(inverse.rle(out))

myfinder <- function(x){
out <- rle(x > 0)
trues <- which(out$values) tmp <- out$lengths[trues]
out\$values[trues[tmp == 1]] <- FALSE
which(inverse.rle(out))
}

myfinder(x)