Keep which(..., arr.ind = TRUE) results that connect

Viewed 3365

I am trying to take the results of a which(..., arr.ind = TRUE) function and remove the rows that are not the first to "connect" with one another.

Examples:

#example 1      example 2      example 3
   row col        row col        row col
     1   4          2   3          1   3
     2   4          2   4          2   5
     4   5          3   5          3   5
     3   6          2   7          4   6
     4   6          3   7          5   6
     3   7          4   7          6   8
     4   7          5   7          9  10
# should become (trimmed.mtx)
   row col        row col        row col
     1   4          2   3          1   3
     4   5          3   5          3   5
                    5   7          5   6
                                   6   8

These examples can be read in using:

example1 <- structure(list(row = c(1L, 2L, 4L, 3L, 4L, 3L, 4L), col = c(4L, 4L, 5L, 6L, 6L, 7L, 7L)), .Names = c("row", "col"), class = "data.frame", row.names = c(NA, -7L))
example2 <- structure(list(row = c(2L, 2L, 3L, 2L, 3L, 4L, 5L), col = c(3L, 4L, 5L, 7L, 7L, 7L, 7L)), .Names = c("row", "col"), class = "data.frame", row.names = c(NA, -7L))
example3 <- structure(list(row = c(1L, 2L, 3L, 4L, 5L, 6L, 9L), col = c(3L, 5L, 5L, 6L, 6L, 8L, 10L)), .Names = c("row", "col"), class = "data.frame", row.names = c(NA, -7L))

The purpose of this is to take a dist matrix of Euclidean distances and turn it into a sequence of point-to-point distances that skip distances below a certain threshold. While there may be other ways to solve this problem, I am very interested in figuring out the best way to do this by filtering out rows from the which-matrix.

Reproducible example of my intended use:

set.seed(81417) # Aug 14th, 2017
# Generate fake location data (temporally sequential)

x <- as.matrix(cbind(x = rnorm(10, 10, 3), y =  rnorm(10, 10, 3)))

# Find euclidean point-to-point distances and remove distances that are less than:
value = 5
# I attempted to do so by calculating an entire Euclidean distance matrix (dist())
# and then finding a path from point-to-nearest-point 
# using distances that are greater than the value 
d <- as.matrix(dist(x[,c("x","y")]))
d[lower.tri(d)] <- 0
mtx <- which(d > value, arr.ind = T)
mtx

# Change from EVERY point-to-point distance (mtx) > value
# to only the "connecting" points that exceed the skipping value
trimmed.mtx <- {?}

# final result
cbind(x[unique(c(trimmed.mtx)),],d[trimmed.mtx])
5 Answers
Related