[R] changing equal values on matrix by same random number

Charles C. Berry cberry at tajo.ucsd.edu
Wed Aug 26 23:46:07 CEST 2009


On Wed, 26 Aug 2009, milton ruser wrote:

> Hi David & all,
>
> It is me again. When I try with a sample matrix (10x10) it appears to be
> good.
> But when I apply to a real 512x512 landscape, with values ranging from 1 to
> 10,000
> It is still time expensive (please, see below):

If the values are integers, try this:

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

HTH,

Chuck

>
> 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, byrow=T
> )
>
> ##  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 )
>
> mymat <-matrix(sample(0:10000,size=512*512, replace=T), ncol=512)
> milton ( x = mymat )
>
> May be using apply series it could be more efficient? I think I need to
> avoid for() looping to speed up it.
>
> cheers
>
> milton
> On Wed, Aug 26, 2009 at 1:30 PM, David Huffer <David.Huffer at csosa.gov>wrote:
>
>> 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:
>>
>>> 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
>>
>> 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:
>>
>>>
>>> On Aug 26, 2009, at 12:53 PM, milton ruser wrote:
>>>
>>> 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(...).
>>>>
>>>
>>> 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.
>>>
>>>
>>>
>>>> I can do it using for(), but it is very time expensive.
>>>> Any help are welcome.
>>>>
>>>> cheers
>>>>
>>>>
>>> David Winsemius, MD
>>> Heritage Laboratories
>>> West Hartford, CT
>>>
>>>
>>
>>         [[alternative HTML version deleted]]
>>
>> ______________________________________________
>> 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<http://www.r-project.org/posting-guide.html>
>> and provide commented, minimal, self-contained, reproducible code.
>>
>
> 	[[alternative HTML version deleted]]
>
> ______________________________________________
> 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




More information about the R-help mailing list