0

I have a matrix similar to this:

m <- matrix(rnorm(100), 100, 50)

and I'd like to change all the values row by row, so that any value above its row (standard deviation) *2 will become 1, otherwise 0 (basically a threshold).

I tried something like this:

cutoff <- function(x){
  x[x < 2*sd(x)] <- 0
  x[x > 2*sd(x)] <- 1
  return(x)
} 

mT <- apply(m, 1, cutoff)

but it's giving me something different. Any help would be very appreciated.

vankappa
  • 71
  • 7

3 Answers3

1

Your code is correct, you need to transpose the result as apply always returns a transposed result (See Why apply() returns a transposed xts matrix? ).

mT <- t(apply(m, 1, cutoff))

You can also reduce the cutoff function to -

cutoff <- function(x){
  as.integer(x > 2*sd(x))
} 

x > 2*sd(x) returns a logical value (TRUE/FALSE), if we convert it to integer it changes TRUE to 1 and FALSE to 0.

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • Thanks, it works now. I still don't understand why it needs transposing? I also don't understand how the as.integer function is working in this case – vankappa Jun 15 '21 at 08:00
  • I edited my answer to include some explanations for both the issues. – Ronak Shah Jun 15 '21 at 08:08
1

Will this work:

t(apply(m, 1, function(x) +(x > 2*sd(x))))
Karthik S
  • 11,348
  • 2
  • 11
  • 25
1

We can use dapply from collapse without transposing and is very efficient

library(collapse)
dapply(m, cutoff, MARGIN = 1)
akrun
  • 874,273
  • 37
  • 540
  • 662