2

I am new to R and I am working on function to manipulate a set of data.

I have a 20 by 5 matrix of values, to that I add a random number between -1 to 1. How can I ensure that all the values in the matrix stay between 0-10 in an efficient and fast manner (without using a loop to check a single value at a time).

These are the rules:

  • If a value is greater than 10, change it to 10
  • If a value is less thatn 0, change it to 0

Any help is appreciated. Thanks!

dfj328
  • 367
  • 2
  • 13

1 Answers1

5

Something like

m[] <- pmax(0,pmin(10,m))

The m[] on the lefthand side (rather than m) ensures that the matrix keeps its structure.

Here's a (probably unnecessary) example:

lwr <- 0; upr <- 10
set.seed(101)
mRaw <- matrix(runif(100, lwr, upr), nrow=20) 
m1 <- sample(c(-1,1),size=100,replace=TRUE)
mAdded <- m1 + mRaw

Now clamp:

mAdded[] <- pmax(lwr,pmin(upr,mAdded))
str(mAdded)
## still a matrix: num [1:20, 1:5] 2.72 0 6.1 7.58 3.5 ...
range(mAdded)  ## 0 10
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
  • 1
    `matrix(sample(c(-1,1),size=100,replace=TRUE),nrow=20)` might be a little more straightforward – Ben Bolker Jun 14 '16 at 12:55
  • Thank you @Ben Bolker. :-) Improved code:`library(dplyr)` `mRaw <- runif(100, 0, 10) %>% as.integer %>% matrix(nrow = 20, ncol = 5)` `m1 <- matrix(sample(c(-1,1),size=100,replace=TRUE),nrow=20)` `mAdded <- m1 + mRaw` `mAdded[] <- pmax(0,pmin(10,mAdded))` – leerssej Jun 14 '16 at 20:18
  • I don't mind pipes in their place, but they don't seem to add much value here ... – Ben Bolker Jun 14 '16 at 20:44
  • I come from a pythonic land. I write in dplyr. :-D – leerssej Jun 14 '16 at 21:00
  • huh, I don't think of pipes as pythonic: http://stackoverflow.com/questions/28252585/functional-pipes-in-python-like-from-dplyr -- at least seems `pandas`-specific ? (and I think I prefer `x %>% fun1() %>% fun2()` to `x.pipe(fun1).pipe(fun2)` anyway ...) – Ben Bolker Jun 14 '16 at 21:04
  • More about the code being tall and thin, and as readable as Robert Frost. – leerssej Jun 14 '16 at 21:10
  • Variant: Matroyshka Doll. `mAdded[] <- pmax(0, pmin(10, matrix(as.integer(runif(100, 0, 10)), nrow = 20, ncol = 5) + matrix(sample(c(-1,1),size=100,replace=TRUE),nrow=20)))` Maybe some folks prefer this, but to me it reads like Henry James. – leerssej Jun 14 '16 at 23:39