Dear S+ers
I posted the following message regarding how to avoid loop (matrix
manipulation) on S-PLUS last week. Here is a summary of the answers
that I received. Many thanks to Samuel Buttrey, Nick Ellis, and Pat Burns.
Original message
----------------
> I would like to avoid a loop from scoring each cell in a
> matrix 'mat' (row x 6) based on some conditions below:
>
> if mat[1,1] is equal to 1 or 2
> then score[1,1] <- cut(myrn[1,1], v1)
>
> if mat[1,1] is equal to 3 or 4
> then score[1,1] <- cut(myrn[1,1], v2)
>
> if mat[1,1] is equal to 5 or 6
> then score[1,1] <- cut(myrn[1,1], v3)
>
> The same condition apply for mat[q,2] and mat[q,3] where q is row.
> But, the condition of column 4-6 is based on w1, w2, and w3. Note that
> 'myrn' is a matrix (row x 6) while v and w are vectors.
"Buttrey, Samuel" <sebuttre@monterey.nps.navy.mil>
----------------------------------------------------------
one.or.two <- mat == 1 | mat == 2
three.or.four <- mat == 3 | mat == 4
five.or.six <- mat == 5 | mat == 6
ind <- one.or.two & col(mat) <= 3 # "ind" is T where mat is 1 or 2
in the first three columns
mat[ind] <- cut (mat[ind], v1)
ind <- three.or.four & col(mat) <= 3
mat[ind] <- cut (mat[ind], v2)
...
ind <- one.or.two & col(mat) >= 4
mat[ind] <- cut (mat[ind], w1) # and so on
"Ellis, Nick (Marine, Cleveland)" <Nick.Ellis@cmis.csiro.au>
------------------------------------------------------------
Here's an outline. I'll ignore the complication of columns and just do it
for one column.( I.e. score, mat and myrn are vectors.)
first do all the cuts in one go
cut.myrn <- cbind(cut(myrn,v1),cut(myrn,v2),cut(myrn,v3))
if we had an index of length 'row' showing which condition is true then we
could subscript cut.yrn thus
score <- cut.myrn[cbind(1:row,index)]
Now we need a way of getting the index. There are lots of ways to do this.
Here is one way
> mat<-round(runif(10,1,6))
> mat
[1] 1 3 4 3 2 4 6 4 2 3
> cut(mat,c(0,2.5,4.5,Inf))
[1] 1 2 2 2 1 2 3 2 1 2
attr(, "levels"):
[1] "0.0+ thru 2.5" "2.5+ thru 4.5" "4.5+ thru Inf"
We can use the result of cut as an index vector, so you could say
score <- cut.myrn[cbind(1:row,cut(mat,c(0,2.5,4.5,Inf)))]
A different, more obvious way is as follows
cond1 <- mat==1 | mat==2
cond2 <- mat==3 | mat==4
cond3 <- mat>4
score <- numeric(row)
score[cond1] <- cut.myrn[cond1,1]
score[cond2] <- cut.myrn[cond2,2]
score[cond3] <- cut.myrn[cond3,3]
Pat Burns <pburns@pburns.seanet.com>
-------------------------------------
In case you haven't gotten an answer yet, unless I'm missing something
you can just get rid of the loop with "q".
Cheers,
Aris,---
Ncl, UK.
-----------------------------------------------------------------------
This message was distributed by s-news@wubios.wustl.edu. To unsubscribe
send e-mail to s-news-request@wubios.wustl.edu with the BODY of the
message: unsubscribe s-news
|