I was playing around a bit to see how I could find the two points in a set of points (or ordered pairs) furthest from each other. Here's what I did: 1) created a Nrow by 2col matrix, so each row contains an x,y coordinate pair. 2) fed the matrix to a nested mapply (cv is my matrix): mapply(function(k,l) mapply(function(x,y,a,b) + sqrt((x-a)^2+(y-b)^2),cv[,1],cv[,2],k,l),cv[,1],cv[,2])->alldist Then I just did which.max(alldist) and found the original two points by figuring out what row, col the results of which.max referred to. So, what's a better, or cleaner way to do all this? That is, is there a function in some package that will do anything like my nested mapply thing, and is there a better tool than which.max for locating a position in a matrix? thanks Carl
Better way to find distances between points in a set?
5 messages · Charles C. Berry, Stavros Macrakis, Carl Witthoft
The 'better way' to do almost anything starts with a reading of the
_posting guide_, which reminds you to
Do your homework before posting [Reasons whyfor deleted]]
* Do help.search("keyword") and apropos("keyword") with different
keywords (type this at the R prompt).
[other homework items deleted]
So, to start with you would have tried:
help.search('distance')
HA! This leads to
dist {stats} Distance Matrix Computation
Well, doesn't that sound promising??
alldist3 <- as.matrix( dist( cv ) ) which( alldist3 == max( alldist3 ), arr.ind=TRUE )
Oh yes, if you are too lazy to look up the posting guide URL, the function help.request() will open it for you when you admit that you haven't yet read it (or lead you thru the further steps to prepare a question to this list if you say that you have read it). HTH, Chuck
On Tue, 9 Dec 2008, Carl Witthoft wrote:
I was playing around a bit to see how I could find the two points in a set of points (or ordered pairs) furthest from each other. Here's what I did: 1) created a Nrow by 2col matrix, so each row contains an x,y coordinate pair. 2) fed the matrix to a nested mapply (cv is my matrix): mapply(function(k,l) mapply(function(x,y,a,b) + sqrt((x-a)^2+(y-b)^2),cv[,1],cv[,2],k,l),cv[,1],cv[,2])->alldist Then I just did which.max(alldist) and found the original two points by figuring out what row, col the results of which.max referred to. So, what's a better, or cleaner way to do all this? That is, is there a function in some package that will do anything like my nested mapply thing, and is there a better tool than which.max for locating a position in a matrix? thanks Carl
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Charles C. Berry (858) 534-2098
Dept of Family/Preventive Medicine
E mailto:cberry at tajo.ucsd.edu UC San Diego
http://famprevmed.ucsd.edu/faculty/cberry/ La Jolla, San Diego 92093-0901
An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20081210/9c31f5ed/attachment.pl>
Ok... then.. I didn't mean to start a flame war, so first off I apologize for firing off my second comment. I think a fair compromise is: I should have at least noted that I got as far as finding dist() (and which.max()), thus showing "some" effort on my part before posting my query. Anyway, I'm happy now because not only did I successfully navigate mapply, I got some great info on dist and which.* from this mailing list. Carl
Stavros Macrakis wrote:
On Tue, Dec 9, 2008 at 11:52 PM, Charles C. Berry <cberry at tajo.ucsd.edu>wrote:
[redacted]
Charles, I am distressed by the nasty tone of your note. Though I certainly
agree that poor queries on this list are an annoyance, and that the posting
guide gives useful advice on what to do before posting, I don't think that
poor queries are a reason to presume bad faith for any but the most flagrant
correspondents ("here is my problem set, solve it for me"). And though I
have not been on this list very long, I have been answering questions on
other lists like this for a long time.
What's more, it seems to me that Witthoft has a legitimate problem. I tried
to solve it myself, and here is what I come up with:
test <- matrix(rnorm(20),ncol=2)
which.max(dist(x),arr.ind=TRUE)
=> Error, though which supports arr.ind, which.max doesn't
Yes, that is documented, but it violates reasonable expectations.
which(dist(x)==max(dist(x)),arr.ind=TRUE)
=> 21 oops, that is a vector index; what about arr.ind?
Apparently the dist class (return class of dist fnc.)
doesn't act as an array here (and which/arr.ind is
happy to treat a vector as an array without warning).
Is this a problem in dist, or a problem in which?
So how do I map back from 21 to 3,7? Nothing obvious.
? `[`, ? array, and ? dist don't seem to help.
So let's convert to a matrix explicitly:
which(as.matrix(dist(x)==max(dist(x))),arr.ind=TRUE)
=> row col
[1,] 21 1
Hmm, that's not right; apparently the == flattened the
dist class into its base vector, which which/arr.ind
helpfully (?) treated as a matrix.
which(as.matrix(dist(x))==max(dist(x)),arr.ind=TRUE)
=> row col
7 7 3
3 3 7
Finally getting useful results; but converting to the array
added in the upper triangular part... oh, well, we need to
choose *which* maximum anyway.
So, as Witthoft said: what's a better, or cleaner way to do all this? And
why aren't R's operators more regular in their behavior? Why doesn't
arr.ind work for which.max? Why doesn't dist(x)==1 return an object of the
same shape as the original dist (as matrix(...)==1 would have), but instead
flatten it? Where does one find the function that maps from a list of array
indices to the corresponding vector index and vice versa?
-s
On Wed, 10 Dec 2008, Stavros Macrakis wrote:
On Tue, Dec 9, 2008 at 11:52 PM, Charles C. Berry <cberry at tajo.ucsd.edu>wrote:
The 'better way' to do almost anything starts with a reading of the
_posting guide_, which reminds you to
Do your homework before posting [Reasons whyfor deleted]]...
Oh yes, if you are too lazy to look up the posting guide URL, the function help.request() will open it for you when you admit that you haven't yet read it (or lead you thru the further steps to prepare a question to this list if you say that you have read it).
Charles, I am distressed by the nasty tone of your note.
Well, I am sorry that my reply caused you distress. I try to provide useful answers. And I often do the 'homework' in the posting guide before responding to be sure I provide useful answers. Sometimes my 'reward' for a post is to receive off-list requests for further help that the 'asker' could have easily worked out by following the 'Do your homework' steps. And I sometimes get those requests even when I point to the excellent self-help resources in my original post. I welcome advice on how to do a better job and do so in a gentler, kinder manner, but I'd like to maintain a focus on strongly encouraging the use of help.request(), the posting guide, and all of the other resources that are already available.
Though I certainly
agree that poor queries on this list are an annoyance, and that the posting
guide gives useful advice on what to do before posting, I don't think that
poor queries are a reason to presume bad faith for any but the most flagrant
correspondents ("here is my problem set, solve it for me"). And though I
have not been on this list very long, I have been answering questions on
other lists like this for a long time.
What's more, it seems to me that Witthoft has a legitimate problem.
To which I provided a solution and to which Carl responded asking for further clarification. I responded to that post too - and I'll admit that it could reasonably be seen as having a 'snarky' tone - but Carl will know when he reads it what he asked to know. I tried
to solve it myself, and here is what I come up with:
test <- matrix(rnorm(20),ncol=2)
which.max(dist(x),arr.ind=TRUE)
=> Error, though which supports arr.ind, which.max doesn't
Yes, that is documented, but it violates reasonable expectations.
which(dist(x)==max(dist(x)),arr.ind=TRUE)
=> 21 oops, that is a vector index; what about arr.ind?
Apparently the dist class (return class of dist fnc.)
doesn't act as an array here (and which/arr.ind is
happy to treat a vector as an array without warning).
Is this a problem in dist, or a problem in which?
So how do I map back from 21 to 3,7? Nothing obvious.
? `[`, ? array, and ? dist don't seem to help.
So let's convert to a matrix explicitly:
which(as.matrix(dist(x)==max(dist(x))),arr.ind=TRUE)
=> row col
[1,] 21 1
Hmm, that's not right; apparently the == flattened the
dist class into its base vector, which which/arr.ind
helpfully (?) treated as a matrix.
which(as.matrix(dist(x))==max(dist(x)),arr.ind=TRUE)
=> row col
7 7 3
3 3 7
Finally getting useful results; but converting to the array
added in the upper triangular part... oh, well, we need to
choose *which* maximum anyway.
OK, so I stopped with the response you just gave and didn't take that next
step to tell Carl to use upper.tri():
which( upper.tri( dist(x) ) &
as.matrix(dist(x))==max(dist(x)),arr.ind=TRUE)
but help.search("upper") gets it easily enough. So does
help.search("triangular").
So, as Witthoft said: what's a better, or cleaner way to do all this?
So I gave him my version of a better, cleaner way. If there is a still better and even cleaner way, I'd be delighted to see it. Carl did not ask any of the questions you listed below. And I didn't see anything in his post that implied he wanted answers to them. Chuck
And
why aren't R's operators more regular in their behavior? Why doesn't
arr.ind work for which.max? Why doesn't dist(x)==1 return an object of the
same shape as the original dist (as matrix(...)==1 would have), but instead
flatten it? Where does one find the function that maps from a list of array
indices to the corresponding vector index and vice versa?
-s
Charles C. Berry (858) 534-2098
Dept of Family/Preventive Medicine
E mailto:cberry at tajo.ucsd.edu UC San Diego
http://famprevmed.ucsd.edu/faculty/cberry/ La Jolla, San Diego 92093-0901