Use max on each element of a matrix

2019-02-21 21:50发布

问题:

> x <- array(-10:10, dim=c(4,5))
> x
     [,1] [,2] [,3] [,4] [,5]
[1,]  -10   -6   -2    2    6
[2,]   -9   -5   -1    3    7
[3,]   -8   -4    0    4    8
[4,]   -7   -3    1    5    9

How do I apply "max(x, 0)" to each element so that I get this matrix:

     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    2    6
[2,]    0    0    0    3    7
[3,]    0    0    0    4    8
[4,]    0    0    1    5    9

回答1:

Use pmax:

pmax(x,0)
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0    0    0    2    6
#[2,]    0    0    0    3    7
#[3,]    0    0    0    4    8
#[4,]    0    0    1    5    9


回答2:

You can use R's indexing function [ to do this directly:

x <- array(-10:10, dim=c(4,5))
x[x < 0] <- 0

This works because x < 0 creates a logical matrix output:

x < 0

     [,1] [,2]  [,3]  [,4]  [,5]
[1,] TRUE TRUE  TRUE FALSE FALSE
[2,] TRUE TRUE  TRUE FALSE FALSE
[3,] TRUE TRUE FALSE FALSE FALSE
[4,] TRUE TRUE FALSE FALSE FALSE

And the resulting matrix is:

     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    2    6
[2,]    0    0    0    3    7
[3,]    0    0    0    4    8
[4,]    0    0    1    5    9

The timing between the two methods is surprisingly similar. Here's a larger example illustrating the comparable timings:

xbigC <- xbigE <- matrix(sample(-100:100, 1e8, TRUE), ncol = 1e4)
system.time(xbigC[xbigC < 0] <- 0)
 #--- 
  user  system elapsed 
   4.56    0.37    4.93 
system.time(xbigE  <- pmax(xbigE,0))
#---
   user  system elapsed 
   4.10    0.51    4.62 
all.equal(xbigC, xbigE)
#---
[1] TRUE


回答3:

It appears that the order of the arguments to pmax() affects the class of what is returned when the input is a matrix:

pmax(0,x)
[1] 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9

pmax(x,0)
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    0    2    6
[2,]    0    0    0    3    7
[3,]    0    0    0    4    8
[4,]    0    0    1    5    9


标签: r matrix max