How can I calculate the area within a contour in R? - r

I'm wondering if it is possible to caclulate the area within a contour in R.
For example, the area of the contour that results from:
sw<-loess(m~l+d)
mypredict<-predict(sw, fitdata) # Where fitdata is a data.frame of an x and y matrix
contour(x=seq(from=-2, to=2, length=30), y=seq(from=0, to=5, length=30), z=mypredict)
Sorry, I know this code might be convoluted. If it's too tough to read. Any example where you can show me how to calculate the area of a simply generated contour would be helpful.
Thanks for any help.

I'm going to assume you are working with an object returned by contourLines. (An unnamed list with x and y components at each level.) I was expecting to find this in an easy to access location but instead found a pdf file that provided an algorithm which I vaguely remember seeing http://finzi.psych.upenn.edu/R/library/PBSmapping/doc/PBSmapping-UG.pdf (See pdf page 19, labeled "-11-") (Added note: The Wikipedia article on "polygon" cites this discussion of the Surveyors' Formula: http://www.maa.org/pubs/Calc_articles/ma063.pdf , which justifies my use of abs().)
Building an example:
x <- 10*1:nrow(volcano)
y <- 10*1:ncol(volcano)
contour(x, y, volcano);
clines <- contourLines(x, y, volcano)
x <- clines[[9]][["x"]]
y <- clines[[9]][["y"]]
level <- clines[[9]][["level"]]
level
#[1] 130
The area at level == 130 (chosen because there are not two 130 levels and it doesn't meet any of the plot boundaries) is then:
A = 0.5* abs( sum( x[1:(length(x)-1)]*y[2:length(x)] - y[1:(length(x)-1)]*x[2:length(x)] ) )
A
#[1] 233542.1

Thanks to #DWin for reproducible example, and to the authors of sos (my favourite R package!) and splancs ...
library(sos)
findFn("area polygon compute")
library(splancs)
with(clines[[9]],areapl(cbind(x,y)))
Gets the same answer as #DWin, which is comforting. (Presumably it's the same algorithm, but implemented within a Fortran routine in the splancs package ...)

Related

Creating my own spider chart in R without using any libraries

I need to create something like a spider chart in R without using any libraries. That’s my code for now. It creates a figure with points number equal to the length of vector ‘a’. However, I’d like each point to be at the distance from the coordinates center equal to a respective number in a vector, for example one point at a distance 1, another at 2, so on. Is it possible to do so?
a <- 1:6
angle <- seq(0, 2*pi, (2*pi)/length(a))
x <- cos(angle)
y <- sin(angle)
plot(x, y,
type = "l")
See ?stars:
a <- 1:6
stars(matrix(a, nrow=1), scale=FALSE)
For future reference, using R's built-in help search would have found this with ??spider

Strange object in vector3d() graphic when using matlib + rgl

I'm trying to plot 3-dimensional vectors (x, y, z coordinates) onto a 3D coordinate system in R like in the picture below. Ideally, I would then like to construct 3d kernel density plots, also like in the image below.
Ideal result of vector plot and 3d kernel density plot
I have a matrix containing ~100 rows and one column for each coordinate (x, y , z). Initially, I tried arrow3D() from the plot3D package but I find the perspective to be sub-par, it's rather difficult to discern directions of the arrows from one perspective in the final plot. Next I tried the rgl package which gives me interactivity - great. Minimal working example:
library(rgl)
library(matlib)
data2 <- data.frame(replicate(6,rnorm(100))) #sample data set for minimum working example
colnames(data2) <- c("x_target", "y_target", "z_target", "x_start", "y_start", "z_start")
x1 <- data2$x_target - data2$x_start
y1 <- data2$y_target - data2$y_start
z1 <- data2$z_target - data2$z_start
vec <- (diag(6,3)) # coordinates for x, y and z axis
rownames(vec) <- c("X", "Y", "Z") # labels for x, y and z axis
z <- as.matrix((data.frame(x=x1, y=y1, z=z1)))
open3d()
vectors3d(vec, color=c(rep("black",3)), lwd=2, radius=1/25)
vectors3d(X=z, headlength=1/25)
(due to the random numbers generator the strange looking rods appear at different coordinates, not exactly like in the image i link to below)
The result of the code above is a version of the image link below. One set of coordinates produces a very strange looking more like rod object which is far longer then the coordinates would produce. If I plot the vectors individually, no such object is created. Anyone have any ideas why this happens? Also, if anyone has a tool (doesn't have to be R), that can create a 3D vector plot like in the first image, I'd be grateful. I find it to be very complicated in R, but I'm definitely a beginner.
Strange object to the right (long red rod that doesn't look like an arrow at all)
Thank you!
This is due to a bug in the matlib package, fixed in verson 0.9.2 of that package. I think you need to install it from Github instead of CRAN to get the bug fix:
devtools::install_github("friendly/matlib")
BTW, if you are using random numbers in a reproducible example, you can make it perfectly reproducible by something like
set.seed(123)
at the start (or some number other than 123). I saw reproducible problems with your example for set.seed(4).

Plot decision boundary from weight vector

How do I plot decision boundary from weight vector?
My original data is 2-dimensional but non-linearly separable so I used a polynomial transformation of order 2 and therefore I ended up with a 6-dimensional weight vector.
Here's the code I used to generate my data:
polar2cart <- function(theta,R,x,y){
x = x+cos(theta) * R
y = y+sin(theta) * R
c=matrix(x,ncol=1000)
c=rbind(c,y)
}
cart2polar <- function(x, y)
{
r <- sqrt(x^2 + y^2)
t <- atan(y/x)
c(r,t)
}
R=5
eps=5
sep=-5
c1<-polar2cart(pi*runif(1000,0,1),runif(1000,0,eps)+R,0,0)
c2<-polar2cart(-pi*runif(1000,0,1),runif(1000,0,eps)+R,R+eps/2,-sep)
data <- data.frame("x" = append(c1[1,], c2[1,]), "y" = append(c1[2,], c2[2,]))
labels <- append(rep(1,1000), rep(-1, 1000))
and here's how it is displayed (using ggplot2):
Thank you in advance.
EDIT: I'm sorry if I didn't provide enough information about the weight vector. The algorithm I'm using is pocket which is a variation of perceptron, which means that the output weight vector is the perpendicular vector that determines the hyper-plane in the feature space plus the bias . Therefore, the hyper-plane equation is , where are the variables. Now, since I used a polynomial transformation of order 2 to go from a 2-dimensional space to a 5-dimensional space, my variables are : and thus the equation for my decision boundary is:
So basically, my question is how do I go about drawing my decision boundary given
PS: I've found a solution while waiting, it might not be the best approach but, it gives the expected results. I'll share it as soon as I finish my project if anyone is interested. Meanwhile, I'd love to hear a better alternative.

Converting "ppp" to multitype

I have been running two unmarked planar point pattern data sets through a series of spatstat functions. Now I would like to use the Kcross.inhom function to describe interaction between the two, but Kcross only works with marked data, so I have combined all x-y data into one csv file and added a column that distinguishes the two. I have established the following point pattern object, but do not understand how to edit the subsequent example of Kcross for my purposes. Or, perhaps there is a better way? Thanks for your help!
# read in data & create ppp
collisionspotholes<-read.csv("cpmulti.csv")
cp<-ppp(collisionspotholes[,3],collisionspotholes[,4],c(40.50390735,40.91115166),c(-74.25262139,-73.7078596))
# synthetic example
pp <- runifpoispp(50)
pp <- pp %mark% factor(sample(0:1, npoints(pp), replace=TRUE))
K <- Kcross(pp, "0", "1")
K <- Kcross(pp, 0, 1) # equivalent
I am not really clear as to what the problem is that you are having. You seem to me to "be there" essentially. However let me, for completeness, spell out the procedure that you should follow:
Let X and Y be your two point patterns (observed, presumably, in the same window).
Put these together into a single pattern:
XY <- superimpose(X=X,Y=Y)
Note that there is no need to dick around with your csv files; it is much more efficient to use the facilities provided by spatstat.
The foregoing syntax produces a multitype point pattern with marks being a factor with levels "X" and "Y". (If you want the levels to be denoted by other symbols you can easily arrange this.)
Then just calculate the inhomogeneous Kcross function:
Ki <- Kcross.inhom(XY,"X","Y")
That is all that there is to it.
Note that the foregoing uses the default method of estimating the intensities of the two patterns, explicitly leave-one-out kernel smoothing with bandwidth chosen by bw.diggle(). There may be better ways of estimating the intensities, perhaps by fitting a parametric model. This depends on the nature of the information available to you.
Interpreting the output of Kcross.inhom() is, IMHO, subtle and difficult.
Be cautious in any conclusions that you draw.
Rolf Turner's answer is correct. However, you say that
I have combined all x-y data into one csv file and added a column that distinguishes the two.
OK, suppose the data frame is called df and it has columns named x and y giving the spatial coordinates and h which is a character vector identifying whether the corresponding point is a pothole (h="p") or a collision (h="c"). Then you could do
X <- ppp(df$x, df$y, xlim, ylim, marks=factor(df$h))
where xlim, ylim are the limits for the spatial coordinates. Or more elegantly
X <- with(df, ppp(x, y, xlim, ylim, marks=factor(h))
Note the use of factor to ensure that the marks are categorical values. Then type
X
to check that you've got a 'multitype point pattern'.
Then you can do, e.g.
K <- Kcross(X)
Ki <- Kcross.inhom(X)
Please read the help files for Kcross, Kcross.inhom for advice about how to use these functions and how to interpret the results.
Incidentally, please do not send the same question to multiple forums at the same time. That is difficult for those who have to answer.

Using R for simple image/pattern-recognition task?

I have an image with many dots, and I would like to extract from it what is the x-y location of each dot.
I already know how to do this manually (there is a package for doing it).
However, is there some way of doing it automatically ?
(My next question will be - is there a a way, when having an image of many lines, to detect where the lines intersect/"touch each other")
Due to requests in the comments, here is an example for an image to "solve" (i.e: extract the data point locations for it)
#riddle 1 (find dots):
plot(cars, pch = 19)
#riddle 2 (find empty center circles):
plot(cars, pch = 1)
#riddle 2 (fine intersection points):
plot(cars, pch = 3)
#riddle 3 (find intersections between lines):
plot(cars, pch = 1, col = "white")
lines(stats::lowess(cars))
abline(v = c(5,10,15,20,25))
Thanks, Tal
(p.s: since I am unfamiliar with this field, I am sorry if I am using the wrong terminology or asking something too simple or complex. Is this OMR?)
The Medical Imaging Task View covers general image provessing, this may be a start.
Following up after Dirk, yes check the medical imaging task view. Also look at Rforge,
Romain Francois has an RJImage package and another image processing package was recently registered. What you are looking for are segmentation algorithms. Your dots problem is much easier than the line problem. The first can be done with an RGB or greyscale filter, just doing some sort of radius search. Detecting linear features is harder. Once you hve the features extracted you can use a sweepline algorithm to detect intersections. EBIimage may have an example for detecting cells in the vignette.
Nicholas
I think you could use package raster to extract xy coordinates from an image with specific values. Have a look at the package vignettes.
EDIT
Can you try this and tell me if it's in the ball park of what you're looking for?
I hope the code with comments is quite self-explanatory. Looking forward to your answer!
library(raster)
rst <- raster(nrows = 100, ncols = 100) #create a 100x100 raster
rst[] <- round(runif(ncell(rst))) #populate raster with values, for simplicity we round them to 0 and 1
par(mfrow=c(1,2))
plot(rst) #see what you've got so far
rst.vals <- getValues(rst) #extract values from rst object
rst.cell.vals <- which(rst.vals == 1) #see which cells are 1
coords <- xyFromCell(rst, rst.cell.vals) #get coordinates of ones
rst[rst.cell.vals] <- NA #set those raster cells that are 1 to NA (you can play with rst[!rst.cell.vals] <- NA to exclude all others)
plot(rst) #a diag plot, should have only one color

Resources