[R] Retain parts of a matrix

David Winsemius dwinsemius at comcast.net
Mon Nov 28 07:08:52 CET 2011


On Nov 28, 2011, at 12:06 AM, Katrina Bennett wrote:

> Sorry for not being more clear.
>
> I'll try to explain again.
>
> I have a rather large DEM and I need to scale daily temperature  
> values for 10 years.

  I have no idea what a DEM might be.
>
> I am using the sapply function to adjust temperatures (t.mean.1.c)  
> based on lapse rates across DEM points (cdem) which meet the  
> condition of elevation being greater than 300m. Below ~300m the  
> lapse rate calculate changes because temperatures decrease with  
> elevation. Above ~300m the lapse rates calculation must account for  
> an inversion, where temperature increases with elevation.
>
> What I would like as a result is the values of the DEM which are  
> lower than 300m to retain a generic lapse rate adjustment, and the  
> DEM values great than 300 to be treating using a different function.
>
>
> t.mean.1.c <- c(-15, -20, -30, -20, -25, -35, -40, -8, 9, 10)
> cdem <- c(300, 400, 700, 900, 1000, 250, 200, 300, 500, 650, 650,  
> 1200,
> 1400, 3200, 2000)
> cdem.mat <- sapply(cdem[which(cdem >= 900)], function(x) get("t.mean. 
> 1.c") - (x * -0.0065)) #this just gives me a
> #result of only the six values
>
> I'm going to make this even more simple to show what I want as output.
>
> t.mean.1.c <- c(-14, -20)
> cdem <- c(300, 400, 700, 900)
> cdem.mat.1 <- sapply(cdem[which(cdem >= 900)], function(x)  
> get("t.mean.1.c") - (x * -0.0065))
> cdem.mat.2 <- sapply(cdem[which(cdem < 900)], function(x)  
> get("t.mean.1.c") + (x * -0.0065))


>
> cdem.mat.1 #right now I get this, which is only the two temperature  
> scaled to the 900 m elevation case
> #       [,1]
> #[1,]  -8.15
> #[2,] -14.15
>
> #What I want:
>
> #       [,1]        [,2]   [,3]         [,4]
> #[1,] -15.95  -16.6    -18.55     -8.15
> #[2,] -21.95   -22.6   -24.55     -14.15

Construct a depth adjustment matrix:
 >   -0.0065 *matrix(cdem, 4,2)* (2*(cdem >= 900)-1)
       [,1]  [,2]
[1,]  1.95  1.95
[2,]  2.60  2.60
[3,]  4.55  4.55
[4,] -5.85 -5.85

Makes two copies of cdem in a column matrix, multiplies by -1 or 1  
depending on the condition, multiplies by you adjustment factor.  
Transposing it will properly oriented to subtract from t.mean.c.1  
using R matrix subtraction (which recycles by columns).

 > t.mean.1.c - t( -0.0065 *matrix(cdem, 4,2)* (2*(cdem >= 900)-1) )
        [,1]  [,2]   [,3]   [,4]
[1,] -15.95 -16.6 -18.55  -8.15
[2,] -21.95 -22.6 -24.55 -14.15


More complicated adjustment choices could be constructed with  
findInterval as an factor-choosing index. For your simple  problem  
case this would suffice..

 > c(0.0065, -0.0065)[findInterval(cdem, c(0,899,Inf))]
[1]  0.0065  0.0065  0.0065 -0.0065


>
> Maybe I can combine in the sapply function an if else statement? I  
> haven't tested the below try.
>
> sapply( if (cdem < 900)] function(x) get("t.mean.1.c") - (x * -0.0065)
> else function(x) get("t.mean.1.c") + (x * -0.0065) )

I don't understand why you keep using get(). Just use the variable name.

>
> Finally, I want to output everything into one single matrix array.

If you stick with matrix operations, that's what you get.

>
> I hope that is more clear.
>
> Thanks for your assistance.
>
> Katrina
>
>
>
>
>
>
> On Sun, Nov 27, 2011 at 7:35 PM, David Winsemius <dwinsemius at comcast.net 
> > wrote:
>
> On Nov 27, 2011, at 10:15 PM, Katrina Bennett wrote:
>
> Hi all,
>
> I'm working to apply a function that will generate a matrix of  
> results only
> when a specific criteria is met.
>
> I want my final results to be a matrix with both the values that  
> meet the
> criteria (the results of the function), and those that to do in the  
> same
> positions in the matrix (the original numbers).
>
> Here's a sample of what I would like to do:
>
> t.mean.1.c <- c(-15, -20, -30, -20, -25, -35, -40, -8, 9, 10)
> cdem <- c(300, 400, 700, 900, 1000, 250, 200, 300, 500, 650, 650,  
> 1200,
> 1400, 3200, 2000)
> cdem.mat <- matrix(NA, 10, 15)
> cdem.mat <- cdem.mat(sapply(cdem[which(cdem >= 900)], function(x)
> ......................^
> cdem.mat is not a function, cannot use "(".
>
>
>
> get("t.mean.1.c") - (x * -0.0065)))
>
> I want cdem.mat to be the same size as the the first call of it,  
> with NA
> values where the cdem is < 899.
>
> You are only offering 10 values as replacements and an unequal  
> number of condition regardless of whether you count the qualifying  
> cdem conditions (6) or the total conditions(15). So you will need to  
> be more clear about how you want the conditions to apply to values.  
> They stepping the audience through the first few decisions and say  
> where you want the values placed. Maybe you should also say whether  
> you expect values to be recycled (the default with matrix assignment).
>
> I suppose it is possible that you want the results of this:
>
> cdem.mat[cdem>899] <-  t.mean.1.c - (cdem * -0.0065)
>
> .... but I'm guessing not.
>
> I thought this would fill it in but it
> seems to just over write it and I only end up with the rows where  
> cdem is
> greater than 900.
>
> Thank you,
>
> Katrina
>
>
>
> -- 
> Katrina E. Bennett
> PhD Student
> University of Alaska Fairbanks
> International Arctic Research Center
> 930 Koyukuk Drive, PO Box 757340
> Fairbanks, Alaska 99775-7340
> 907-474-1939 office
> 907-385-7657 cell
> kebennett at alaska.edu
>
>
> Personal Address:
> UAF, PO Box 752525
> Fairbanks, Alaska 99775-2525
> bennett.katrina at gmail.com
>
>        [[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.
>
> David Winsemius, MD
> West Hartford, CT
>
>

David Winsemius, MD
West Hartford, CT



More information about the R-help mailing list