Skip to content

changing equal values on matrix by same random number

10 messages · David Huffer, David Winsemius, milton ruser +2 more

#
You want to replace all 1s each with the same random nuumber from the uniform distribution, then all 2s each with the same random nuumber from the uniform distribution, and so forth?  Are the arguments (i.e., the min and max of the distribution) to each call to runif identical?

--
 David
?
 -----------------------------------------------------
 David Huffer, Ph.D.               Senior Statistician
 CSOSA/Washington, DC           david.huffer at csosa.gov
 -----------------------------------------------------

-----Original Message-----
From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of milton ruser
Sent: Wednesday, August 26, 2009 12:54 PM
To: r-help at r-project.org
Subject: [R] changing equal values on matrix by same random number

Dear all,

I have about 30,000 matrix (512x512), with values from 1 to N.
Each value on a matrix represent a habitat patch on my
matrix (i.e. my landscape). Non-habitat are stored as ZERO.
No I need to change each 1-to-N values for the same random
number.

Just supose my matrix is:
mymat<-matrix(c(1,1,1,0,0,0,0,0,0,0,0,
0,0,0,0,2,2,2,0,0,0,0,
0,0,0,0,2,2,2,0,0,0,0,
3,3,0,0,0,0,0,0,0,4,4,
3,3,0,0,0,0,0,0,0,0,0), nrow=5)

I would like that all cells with 1 come to be
runif(1,min=0.4, max=0.7), and cells with 2
be replace by another runif(...).

I can do it using for(), but it is very time expensive.
Any help are welcome.

cheers

milton


______________________________________________
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.
#
On Aug 26, 2009, at 12:53 PM, milton ruser wrote:

            
First the wrong way and then the right way:

 > mymat[mymat==1] <- runif(1,min=0.4,max=0.7)
 > mymat
           [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
[1,] 0.4573161    0    0    2    0    0    0    0    0     3     0
[2,] 0.4573161    0    0    2    0    2    0    0    0     0     0
[3,] 0.4573161    0    0    2    0    2    0    0    4     0     0
[4,] 0.0000000    0    0    0    0    2    3    0    4     0     0
[5,] 0.0000000    0    0    0    0    0    3    0    3     0     0

All the values are the same, clearly not what was desired.

Put it back to your starting point:

 > mymat<-matrix(c(1,1,1,0,0,0,0,0,0,0,0,
+ 0,0,0,0,2,2,2,0,0,0,0,
+ 0,0,0,0,2,2,2,0,0,0,0,
+ 3,3,0,0,0,0,0,0,0,4,4,
+ 3,3,0,0,0,0,0,0,0,0,0), nrow=5)

# So supply the proper number of random realizations:

 > mymat[mymat==1] <- runif(sum(mymat==1),min=0.4,max=0.7)
 > mymat
           [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
[1,] 0.5745665    0    0    2    0    0    0    0    0     3     0
[2,] 0.6956418    0    0    2    0    2    0    0    0     0     0
[3,] 0.6935466    0    0    2    0    2    0    0    4     0     0
[4,] 0.0000000    0    0    0    0    2    3    0    4     0     0
[5,] 0.0000000    0    0    0    0    0    3    0    3     0     0

If you want to supply a matrix of max and min values for the other  
integers there would probably be an *apply approach that could be used.
David Winsemius, MD
Heritage Laboratories
West Hartford, CT
#
You could try either of the two examples below. They both assume that min and max are invariant: 

mymat <- matrix (
  c (
    1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2
    , 2 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 , 2 , 2 , 0 , 0
    , 0 , 0 , 3 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 4 , 4 , 3 , 3
    , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
  ) , nrow = 5
)

##  this way gives same random values for
##  each integer between 0 and
##  max (mymat):

milton <- function ( x , min = 0.4 , max = 0.7 ) {
  .rep <- runif ( n = max ( x ) , min = min , max = max )
  for ( i in 1:max ( x ) ) {
  x[x == i] <- .rep[i]
  }
  x
}
milton ( x = mymat )

##  this way gives different random values
##  for each integer between
##  0 and max (mymat):

milton <- function ( x , min = 0.4 , max = 0.7 ) {
  for ( i in 1:max ( x ) ) {
    x [ x == i ] <- runif (
      sum ( x == i )
      , min = min
      , max = max
    )
  }
  x
}
milton ( x = mymat )
 
--
 David
?
 -----------------------------------------------------
 David Huffer, Ph.D.               Senior Statistician
 CSOSA/Washington, DC           david.huffer at csosa.gov
 -----------------------------------------------------


-----Original Message-----
From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of milton ruser
Sent: Wednesday, August 26, 2009 1:18 PM
To: David Winsemius
Cc: r-help at r-project.org
Subject: Re: [R] changing equal values on matrix by same random number

Hi David,
Thanks for the reply. This is what I need:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
[1,] 0.4573161    0    0    2    0    0    0    0    0     3     0
[2,] 0.4573161    0    0    2    0    2    0    0    0     0     0
[3,] 0.4573161    0    0    2    0    2    0    0    4     0     0
[4,] 0.0000000    0    0    0    0    2    3    0    4     0     0
[5,] 0.0000000    0    0    0    0    0    3    0    3     0     0

But as my real landscapes have values from 1 to large number (~10,0000),
so I think that if I put this on a for() looping it will be very time
expensive,
and as I have a lot of landscapes, I need to speed up it.

Any suggestion?

bests

milton
On Wed, Aug 26, 2009 at 1:12 PM, David Winsemius <dwinsemius at comcast.net>wrote:

            
______________________________________________
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.
#
Bill Dunlap
TIBCO Software Inc - Spotfire Division
wdunlap tibco.com
Is the following what you want?  It uses the small
integers in mymat as indices into a vector of N random
numbers.
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
[1,]    1    0    0    2    0    0    0    0    0     3     0
[2,]    1    0    0    2    0    2    0    0    0     0     0
[3,]    1    0    0    2    0    2    0    0    4     0     0
[4,]    0    0    0    0    0    2    3    0    4     0     0
[5,]    0    0    0    0    0    0    3    0    3     0     0
[1] 0 4
N<-max(mat)
     tmp <- mat[mat>0]
     tmp <- runif(N, 0.4, 0.7)[tmp]
     mat[mat>0] <- tmp
     mat
 }
[,1] [,2] [,3]      [,4] [,5]      [,6]      [,7] [,8]
[,9]
[1,] 0.5361427    0    0 0.6727491    0 0.0000000 0.0000000    0
0.0000000
[2,] 0.5361427    0    0 0.6727491    0 0.6727491 0.0000000    0
0.0000000
[3,] 0.5361427    0    0 0.6727491    0 0.6727491 0.0000000    0
0.5357566
[4,] 0.0000000    0    0 0.0000000    0 0.6727491 0.6417832    0
0.5357566
[5,] 0.0000000    0    0 0.0000000    0 0.0000000 0.6417832    0
0.6417832
         [,10] [,11]
[1,] 0.6417832     0
[2,] 0.0000000     0
[3,] 0.0000000     0
[4,] 0.0000000     0
[5,] 0.0000000     0

The 3 lines involving tmp could be collapsed into one, making
things more obscure
    mat[mat>0] <- runif(N, 0.4, 0.7)[mat[mat>0]] 

Bill Dunlap
TIBCO Software Inc - Spotfire Division
wdunlap tibco.com
#
On Wed, 26 Aug 2009, milton ruser wrote:

            
If the values are integers, try this:

mymat[ mymat > 0 ] <- runif( max(mymat), min=0.4, max=0.7 )[ mymat ]

HTH,

Chuck
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