Bookmark and Share

Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at statalist.org.


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: st: Mata equivalent for R's which() or matlabs find() functions?


From   Nick Cox <[email protected]>
To   "'[email protected]'" <[email protected]>
Subject   RE: st: Mata equivalent for R's which() or matlabs find() functions?
Date   Wed, 2 Mar 2011 19:20:39 +0000

This now looks like a different question, so the answer is different. That's understandable. 

You are, it seems, going to feed your function a matrix that is already 1s when elements are what interest you and 0s otherwise. That being so, you can loop over rows and columns and pick up the subscripts that interest you. Here's an alternative version. 

real matrix my_which(real matrix X)
{

real matrix sub  
real scalar i, j 
sub = J(0,2,.)

for (i = 1; i <= rows(X); i++) {
	for (j = 1; j <= cols(X); j++) { 
		if (X[i,j] == 1) sub = sub \ (i,j)
	} 	
}

return(sub)
}

This is longer than yours because I add declarations. But I don't see the need to bring in -select()- at all. A nuance is that if you initialise the subscripts matrix as having 0 rows then there is nothing to throw away at the end: a little mind-boggling, but Mata understands. 

Nothing stops this function being used for string comparisons, as in something like 

: frog = "foo", "bar"

: my_which(frog :== "foo")
       1   2
    +---------+
  1 |  1   1  |
    +---------+

-my_which()- sees the _result_ of 

frog :== "foo"

which is numeric. So, although the generality of -transmorphic- does no harm, it is not needed either for your design. 

Nick 
[email protected] 

Sebastian Eppner

Thanks a lot for the replies. The select() function really comes close
to what I am looking for (looking into Ben Janns mm_which() tells me
he did exactly what Bill suggested).

The only problem for me is, that this strategy can be applied to
vectors only. Because really I am interested in the position of the
rowmax values of a MATRIX, I wrote a function that uses loops to solve
the issue (I write the results into a matrix that looks like the one
the R which produces); i am a mata newby, so its probably not elegant
at all (but working):


transmorphic matrix which_test(transmorphic matrix I)
{
r = J(1,2,.)

for (i=1; i<=rows(I);i++) {

s = I[i,.]

ir = select(1..cols(I),s)
		for (o=1; o<=cols(ir);o++) {
		r = r \ i,ir[.,o]
		}
}
return(r[2..rows(r),.])
}

mata mosave which_test(), dir(PERSONAL) replace
end


Lets take a vector v = 1,3,3 \ 6,5,4
Now you can do funny things like:

which_test(v:==rowmax(v))

that produces the matrix 1,2 \ 1,3 \ 2,1
(so we have 2 maximums in row 1 and 1 in row 2)

or look for the position of the matrix maximum:
which_test(v:==max(v))

which returns a vector 2,1 (maximum is in row 2, column 1)

and so on...

Again thx for the help. I would be interested if I just wrote smth
that is already out there. Maybe it is a good idea to include
something like this as  find() or which() in mata.

Sebastian

On Wed, Mar 2, 2011 at 1:49 AM, Nick Cox <[email protected]> wrote:

> Bill's approach is illustrated here only on examples in which each
> column contains a single element. Consider an example from an earlier
> post
>
> : y = J(4,2,(1..4))
>
> : y
>       1   2   3   4   5   6   7   8
>    +---------------------------------+
>  1 |  1   2   3   4   1   2   3   4  |
>  2 |  1   2   3   4   1   2   3   4  |
>  3 |  1   2   3   4   1   2   3   4  |
>  4 |  1   2   3   4   1   2   3   4  |
>    +---------------------------------+
>
> If we are testing whether any column is all 4s, then it seems we need
> something like -colmax()- to produce conformable arguments.
>
> : select((1..cols(y)), colmax(y :== J(4,1,4)))
>       1   2
>    +---------+
>  1 |  4   8  |
>    +---------+
>
> In other cases in which a condition could be true or false for
> individual elements in a column
>
> : x = J(2,4,(1,2,3,4\4,3,2,1))
>
> : x
>        1    2    3    4    5    6    7    8    9   10   11   12   13
>  14   15   16
>    +---------------------------------------------------------------------------------+
>  1 |   1    2    3    4    1    2    3    4    1    2    3    4    1
>  2    3    4  |
>  2 |   4    3    2    1    4    3    2    1    4    3    2    1    4
>  3    2    1  |
>  3 |   1    2    3    4    1    2    3    4    1    2    3    4    1
>  2    3    4  |
>  4 |   4    3    2    1    4    3    2    1    4    3    2    1    4
>  3    2    1  |
>    +---------------------------------------------------------------------------------+
>
> we need -colmin()- or -colmax()- to distinguish between "any true" and
> "all true".
>
> : select((1..cols(x)), colmax(x :>= 3))
>        1    2    3    4    5    6    7    8    9   10   11   12   13
>  14   15   16
>    +---------------------------------------------------------------------------------+
>  1 |   1    2    3    4    5    6    7    8    9   10   11   12   13
>  14   15   16  |
>    +---------------------------------------------------------------------------------+
>
> : select((1..cols(x)), colmin(x :>= 3))
>
> : select((1..cols(x)), colmin(x :>= 2))
>        1    2    3    4    5    6    7    8
>    +-----------------------------------------+
>  1 |   2    3    6    7   10   11   14   15  |
>    +-----------------------------------------+
>
> Incidentally, I like to test for even and odd using -mod(,)-.
>
> : mod(2,2) == 0
>  1
>
> : mod(3,2) == 0
>  0
>
> : !mod(3,2)
>  0
>
> : !mod(2,2)
>  1
>
> Nick
>
>
> On Tue, Mar 1, 2011 at 8:34 PM, William Gould, StataCorp LP
> <[email protected]> wrote:
>> Sebastian Eppner <[email protected]> writes,
>>
>>> I am desperately looking for a mata function that gives me the column
>>> indices of columns that satisfy certain conditions.
>>
>> Just to fix ideas, let's say we have
>>
>>      x = (2, 4, 1, 6)
>>
>> and we want to obtain the column indices for which x is even.  We
>> want (1, 2, 4).  The answer is:
>>
>>        : s = (floor(x:/2)*2 :== x)
>>
>>        : result = select((1..4), s)
>>
>>        : result
>>               1   2   3
>>            +-------------+
>>          1 |  1   2   4  |
>>            +-------------+
>>
>> In the above, s is the selection vector; the vector contains 0 for
>> columns that should be omitted, and nonzero for columns to be included.
>> I set up s to contain 1s and 0s, with 1s marking the even numbers.
>>
>> (1..4) creates the vector (1, 2, 3, 4).
>>
>> (1..6) would create (1, 2, 3, 4, 5, 6)
>>
>> Thus, (1..cols(s)), which Mata will understand, creates a vector of
>> indices.
>>
>> The select() function selects columns (or rows) from one matrix based on
>> a selection vector.
>>

*
*   For searches and help try:
*   http://www.stata.com/help.cgi?search
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/


© Copyright 1996–2018 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   Site index