Besides being a much better solution, it displays ties (which I see as a
benefit). For example, if I ask for 5 I get 8 for top values since 12 occurs
3 times.

Here is the same thing David posted with slight mods to generalize it a bit
for cnt:

x <- swiss$Education[1:25]
dat = matrix(x,5,5)
colnames(dat) = c('a','b','c','d','e')
rownames(dat) = c('z','y','x','w','v')
cnt = 5
#===============================================
dattop <- which(dat >= c(dat)[rev(order(dat))][cnt], arr.ind=TRUE)
 rbind( top = dat[dattop],
         rows = rownames(dat)[ dattop[,1] ],
         cols = colnames(dat)[ dattop[,2] ])

datbot <- which(dat <= c(dat)[order(dat)][cnt], arr.ind=TRUE)
rbind( bot = dat[datbot],
         rows = rownames(dat)[ datbot[,1] ],
         cols = colnames(dat)[ datbot[,2] ])

Thanks David!

Ben


On Thu, Oct 13, 2011 at 9:48 AM, David Winsemius <dwinsem...@comcast.net>wrote:

>
> On Oct 13, 2011, at 10:42 AM, Ben qant wrote:
>
>  Here is a more R'sh solution (speed unknown).
>>
>
> Really? The intermediate, potentially large, objects seem to be
> proliferating.
>
>
>  Courtesy of Mark Leeds (I
>> modified it a bit to generalize it for a cnt input and get min and max).
>> Again, getting cnt highest and lowest values in the entire matrix and
>> display the data point row and column names with each:
>>
>
> 1) For max (or min) I would have thought that one could have much more
> easily gathered the maximum and minimum locations with:
>
>  which(x == max(x), arr.ind=TRUE)   # Bert Gunter's discarded suggestion
>
> ... and used the results as indices into x or rownames(x) or colnames(x).
> But I made no earlier comments because it did not appear that you had
> provided the swiss$Education object in a form that could be easily extracted
> for testing. I see now that setting up a similar object was fairly easy, but
> would encourage you to consider the `dput` function for such problem
> construction in the future;
>
> dat2 <- matrix(sample(1:25, 25), 5,5)
> colnames(dat2) = c('a','b','c','d','e')
> rownames(dat2) = c('z','y','x','w','v')
> arrns <- which(dat2 == max(dat2), arr.ind=TRUE)
> > arrns
>  row col
> v   5   1
> > colnames(dat2)[arrns[,2]] ; rownames(dat2)[arrns[,1]]
> [1] "a"
> [1] "v"
>
> 2) For display of all results with row/column labels :
>
> rbind(dat2, rownames(dat2)[row(dat2)], colnames(dat2)[row(dat2)])
>
> 3) For display of values of "bottom five" and top five:
>
>  dat2five <- which(dat2 <= c(dat2)[order(dat2)][5], arr.ind=TRUE)
>  rbind( dat2LT5= dat2[dat2five],
>          Rows = rownames(dat2)[ dat2five[,1] ],
>          Cols = colnames(dat2)[ dat2five[,2] ])
> #--------------
>
>        [,1] [,2] [,3] [,4] [,5]
> dat2LT5 "2"  "3"  "5"  "1"  "4"
> Rows    "x"  "w"  "y"  "y"  "x"
> Cols    "a"  "a"  "c"  "d"  "d"
>
> dat2topfive <- which(dat2 >= c(dat2)[rev(order(dat2))][5], arr.ind=TRUE)
>  rbind( dat2top5= dat2[dat2topfive],
>          Rows = rownames(dat2)[ dat2topfive[,1] ],
>          Cols = colnames(dat2)[ dat2topfive[,2] ])
> #---------------
>
>         [,1] [,2] [,3] [,4] [,5]
> dat2top5 "24" "25" "23" "22" "21"
> Rows     "z"  "v"  "y"  "w"  "v"
> Cols     "a"  "a"  "b"  "e"  "e"
>
>
>
>
>
>
>>  x <- swiss$Education[1:25]
>>> dat = matrix(x,5,5)
>>> colnames(dat) = c('a','b','c','d','e')
>>> rownames(dat) = c('z','y','x','w','v')
>>> cnt = 10
>>> #=============================**==================
>>> print(dat)
>>>
>>  a  b  c  d  e
>> z 12  7  6  2 10
>> y  9  7 12  8  3
>> x  5  8  7 28 12
>> w  7  7 12 20  6
>> v 15 13  5  9  1
>>
>>>
>>> # MAKE IT A VECTOR FOR EASIER ORDERING
>>> datasvec <- as.vector(dat)
>>> # ORDER IT
>>> datasvecordered<- order(datasvec)
>>> # RECYCLE ROWS AND COLUMNS NAMES FOR EASIER MAPPING
>>> recycledcols <- rep(colnames(dat),each=nrow(**dat))
>>> recycledrows <- rep(rownames(dat),times=ncol(**dat))
>>>
>>> # GET THE VALUES, THE ROW NAMES AND THE COLUMN NAMES
>>> len = length(datasvecordered)
>>> rr_len = length(recycledrows)
>>>
>>>  rbind(datasvec[**datasvecordered][(len-cnt):**len],recycledrows[**
>> datasvecordered][(rr_len-cnt):**rr_len],recycledcols[**
>> datasvecordered][(rr_len-cnt):**rr_len])
>>    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
>> [1,] "9"  "9"  "10" "12" "12" "12" "12" "13" "15" "20"  "28"
>> [2,] "y"  "v"  "z"  "z"  "y"  "w"  "x"  "v"  "v"  "w"   "x"
>> [3,] "a"  "d"  "e"  "a"  "c"  "c"  "e"  "b"  "a"  "d"   "d"
>>
>>>
>>>  rbind(datasvec[**datasvecordered][1:cnt],**
>> recycledrows[datasvecordered][**1:cnt],recycledcols[**
>> datasvecordered][1:cnt])
>>    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
>> [1,] "1"  "2"  "3"  "5"  "5"  "6"  "6"  "7"  "7"  "7"
>> [2,] "v"  "z"  "y"  "x"  "v"  "z"  "w"  "w"  "z"  "y"
>> [3,] "e"  "d"  "e"  "a"  "c"  "c"  "e"  "a"  "b"  "b"
>>
>> enjoy
>>
>> ben
>>
>> On Wed, Oct 12, 2011 at 11:47 AM, Ben qant <ccqu...@gmail.com> wrote:
>>
>>  Hello,
>>>
>>> This is my solution. This is pretty fast (tested with a larger data set)!
>>> If you have a more elegant way to do it (of similar speed), please reply.
>>> Thanks for the help!
>>>
>>> ################## get highest and lowest values and names of a matrix
>>> # create sample data
>>>
>>> x <- swiss$Education[1:25]
>>> dat = matrix(x,5,5)
>>> colnames(dat) = c('a','b','c','d','e')
>>>
>>> rownames(dat) = c('z','y','x','w','v')
>>>
>>> #my solution
>>>
>>> nms = dimnames(dat) #get matrix row and col names
>>> cnt = 10 # number of max and mins to get
>>>
>>> tmp = dat
>>> mxs = list("list",cnt)
>>> mns = list("list",cnt)
>>> for(i in 1:cnt){
>>>  #get maxes
>>>  mx_dims = arrayInd(which.max(tmp), dim(tmp)) # get max dims for entire
>>> matrix note: which.max also removes NA's
>>>  mx_nm = c(nms[[1]][mx_dims[1]],nms[[2]**][mx_dims[2]]) #get names
>>>  mx = tmp[mx_dims] # get max value
>>>  mxs[[i]] = c(mx,mx_nm) # add max and dim names to list of maxes
>>>  tmp[mx_dims] = NA #removes last max so new one is found
>>>
>>>  #get mins (basically same as above)
>>>  mn_dims = arrayInd(which.min(tmp), dim(tmp))
>>>  mn_nm = c(nms[[1]][mn_dims[1]],nms[[2]**][mn_dims[2]])
>>>  mn = tmp[mn_dims]
>>>  mns[[i]] = c(mn,mn_nm)
>>>  tmp[mn_dims] = NA
>>> }
>>>
>>> mxs
>>> mns
>>>
>>> # end
>>>
>>> Regards,
>>>
>>> Ben
>>>
>>>
>>> On Tue, Oct 11, 2011 at 5:32 PM, "Dénes TÓTH" <tde...@cogpsyphy.hu>
>>> wrote:
>>>
>>>
>>>> which.max is even faster:
>>>>
>>>> dims <- c(1000,1000)
>>>> tt <- array(rnorm(prod(dims)),dims)
>>>> # which
>>>> system.time(
>>>> replicate(100, which(tt==max(tt), arr.ind=TRUE))
>>>> )
>>>> # which.max (& arrayInd)
>>>> system.time(
>>>> replicate(100, arrayInd(which.max(tt), dims))
>>>> )
>>>>
>>>> Best,
>>>> Denes
>>>>
>>>>  But it's simpler and probably faster to use R's built-in capabilities.
>>>>> ?which ## note the arr.ind argument!)
>>>>>
>>>>> As an example:
>>>>>
>>>>> test <- matrix(rnorm(24), nr = 4)
>>>>> which(test==max(test), arr.ind=TRUE)
>>>>>    row col
>>>>> [1,]   2   6
>>>>>
>>>>> So this gives the row and column indices of the max, from which row and
>>>>> column names can easily be obtained from the dimnames attribute of the
>>>>> matrix.
>>>>>
>>>>> Note: This assumes that the object in question is a matrix, NOT a data
>>>>> frame, for which it would be slightly more complicated.
>>>>>
>>>>> -- Bert
>>>>>
>>>>>
>>>>> On Tue, Oct 11, 2011 at 3:06 PM, Carlos Ortega
>>>>> <c...@qualityexcellence.es>**wrote:
>>>>>
>>>>>  Hi,
>>>>>>
>>>>>> With this code you can find row and col names for the largest value
>>>>>> applied
>>>>>> to your example:
>>>>>>
>>>>>> r.m.tmp<-apply(dat,1,max)
>>>>>> r.max<-names(r.m.tmp)[r.m.tmp=**=max(r.m.tmp)]
>>>>>>
>>>>>> c.m.tmp<-apply(dat,2,max)
>>>>>> c.max<-names(c.m.tmp)[c.m.tmp=**=max(c.m.tmp)]
>>>>>>
>>>>>> It's inmediate how to get the same for the smallest and build a
>>>>>>
>>>>> function
>>>>
>>>>> to
>>>>>> calculate everything and return a list.
>>>>>>
>>>>>>
>>>>>> Regards,
>>>>>> Carlos Ortega
>>>>>> www.qualityexcellence.es
>>>>>>
>>>>>> 2011/10/11 Ben qant <ccqu...@gmail.com>
>>>>>>
>>>>>>  Hello,
>>>>>>>
>>>>>>> I'm looking to get the values, row names and column names of the
>>>>>>>
>>>>>> largest
>>>>>>
>>>>>>> and
>>>>>>> smallest values in a matrix.
>>>>>>>
>>>>>>> Example (except is does not include the names):
>>>>>>>
>>>>>>>  x <- swiss$Education[1:25]
>>>>>>>> dat = matrix(x,5,5)
>>>>>>>> colnames(dat) = c('a','b','c','d','c')
>>>>>>>> rownames(dat) = c('z','y','x','w','v')
>>>>>>>> dat
>>>>>>>>
>>>>>>>  a  b  c  d  c
>>>>>>> z 12  7  6  2 10
>>>>>>> y  9  7 12  8  3
>>>>>>> x  5  8  7 28 12
>>>>>>> w  7  7 12 20  6
>>>>>>> v 15 13  5  9  1
>>>>>>>
>>>>>>>  #top 10
>>>>>>>> sort(dat,partial=n-9:n)[(n-9):**n]
>>>>>>>>
>>>>>>> [1]  9 10 12 12 12 12 13 15 20 28
>>>>>>>
>>>>>>>> # bottom 10
>>>>>>>> sort(dat,partial=1:10)[1:10]
>>>>>>>>
>>>>>>> [1] 1 2 3 5 5 6 6 7 7 7
>>>>>>>
>>>>>>> ...except I need the rownames and colnames to go along for the ride
>>>>>>>
>>>>>> with
>>>>>>
>>>>>>> the
>>>>>>> values...because of this, I am guessing the return value will need to
>>>>>>>
>>>>>> be
>>>>>> a
>>>>>>
>>>>>>> list since all of the values have different row and col names (which
>>>>>>>
>>>>>> is
>>>>>>
>>>>>>> fine).
>>>>>>>
>>>>>>> Regards,
>>>>>>>
>>>>>>> Ben
>>>>>>>
>>>>>>
> David Winsemius, MD
> West Hartford, CT
>
>

        [[alternative HTML version deleted]]

______________________________________________
R-help@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.

Reply via email to