0
votes

I have a dataset of XY points that looks like this

x<-c(2,4,6,3,7,9,1)
y<-c(6,4,8,2,9,6,1)
id<-c("a","b","c","d","e","f","g")
dataset<-data.frame(cbind(x,y,id))

I would like to connect all combinations of all points with spatial lines, with lines named with combinations of the points that they're connecting

In "attributes table" that results from the output, names for spatial lines might look like this:

a_b
a_c
a_d
a_e
a_f
a_g
b_a
b_c
b_d
b_e
b_f
b_g
c_a
etc.
2
combn(id, 2, FUN = function(x) paste(x, collapse = "_"))?David Arenburg

2 Answers

3
votes

I'm speculating a bit here as to what exactly you wanted, but I think you want to visualize the connections from any point to the others. If that's the case, then this might work. But first, some assumptions:

  • Your x and y coordinates are starting points. Consequently, id are thus id.origin
  • All other points will need to become "destinations", and then their own coordinates will become x_destination and so on.

< disclaimer> There should be a better, more elegant way to do this. I'd appreciate if someone more experienced can jump in and show me any of the *ply ways to do it. < /disclaimer>

Replicate the dataframe to cover for all possible combinations

dataset<-do.call(rbind, replicate(7, dataset, simplify=FALSE))

Now, create a matrix with all the same destination points, mixed:

nm=matrix(ncol=3)
for (i in 1:7){
    nm<-rbind(nm,do.call(rbind,replicate(7,as.matrix(dataset[i,]),simplify=FALSE)))
}
nm<-nm[-1,]

Rename the columns of matrix, so they make sense, and bind the existing data frame with the new matrix

colnames(nm)<-c("x2","y2","id.dest")
newds<-cbind(dataset,as.data.frame(nm))

Remove duplicated trajectories:

newds<-newds[-which(newds$id.origin==newds$id.dest),]

and plot the result using geom_segment:

p<-ggplot(newds,aes(x=x,y=y))+geom_segment(aes(xend=x2,yend=y2))

There is a way to name the segments, but from observing the plot I would't suggest doing it. Instead you might consider naming the points using geom_text (other options are available, see ?annotate for one).

p<-p + geom_text(aes(x=1.8,y=6.1,label="a"))

That will produce a plot like the one here: Quiver-like plot of distances

3
votes

The whole solution looks like this:

plot(dataset$x,dataset$y)

Replicate the dataframe to cover for all possible combinations

dataset<-do.call(rbind, replicate(7, dataset, simplify=FALSE))

Now, create a matrix with all the same destination points, mixed:

nm=matrix(ncol=3)
for (i in 1:7){
  nm<-rbind(nm,do.call(rbind,replicate(7,as.matrix(dataset[i,]),simplify=FALSE)))
}
nm<-nm[-1,]

Rename the columns of matrix, so they make sense, and bind the existing data frame with the new matrix

colnames(nm)<-c("x2","y2","id.dest")
newds<-cbind(dataset,as.data.frame(nm))

Remove duplicated trajectories:

newds1<-newds[-which(newds$id==newds$id.dest),]

library(ggplot2)

Converting destination x & y to numeric from factor

newds1$x2<-as.numeric(as.character(newds1$x2)) #converting from factor to numeric
newds1$y2<-as.numeric(as.character(newds1$y2))

Plotting the destination points . . .same as the origin points

plot(newds1$x, newds1$y) 
plot(newds1$x2, newds1$y2, col="red") 

Now use code from this answer:

Convert Begin and End Coordinates into Spatial Lines in R

Raw list to store Lines objects:

l <- vector("list", nrow(newds1)) #

This l is now an empty vector w/ number of rows defined by length (nrow) of newds1

Splitting origin and destination coordinates so I can run this script:

origins<-data.frame(cbind(newds1$x, newds1$y))
destinations<-data.frame(cbind(newds1$x2, newds1$y2))

library(sp)
for (i in seq_along(l)) {
  l[[i]] <- Lines(list(Line(rbind(origins[i, ], destinations[i,]))), as.character(i))
}

l.spatial<-SpatialLines(l)
plot(l.spatial, add=T)