jalapic
jalapic

Reputation: 14202

Setting min and max values for matrix cells when running a for loop in r

I am running code in a for loop that undertakes some simple arithmetic on individual cells in a matrix. All cells of the matrix should always have values between 0 and 1. The values in the matrix should never become negative or exceed 1. I cannot work out using traditional 'min' and 'max' limit setting how to work this out.

Example data:

x<-1:5
y<-runif(length(x)*length(x),0,1)
M<-matrix(y, length(x), length(x))

e.g. subtracting 0.01 from every cell (in my real situation, the 0.01 to be subtracted at each iteration of the loop is from a specific cell and not from every cell as written here, but I think that shouldn't effect how to set the min/max?

for (i in 1:50){
M[,]<-M[,]-0.01
}

e.g. or if adding 0.01 to every cell of the matrix:

for (i in 1:50){
M[,]<-M[,]+0.01
}

If returning the matrix after either of these for loops, the values in the matrix will not be contained to within the 0 and 1 range like I desire them to be. I'm flummoxed as to how to do this.

If I was doing something specific to one 'cell' of the matrix, e.g.

for (i in 1:100){
M[3,4]<-M[3,4]-0.01
}

would this change how to set min/max values?

Upvotes: 1

Views: 2292

Answers (2)

ThatGuy
ThatGuy

Reputation: 1233

I think there are two ways to do this:

1 - post-hoc

Run your loops through and get your results (outside of the range), then force the data to be within your min/max values with:

M[which(M<min)] = min
M[which(M>max)] = max

2 - within the loop

You could modify your assignment function to read

for (i in 1:50){
    M[which(M<max)] <- M[which(M<max)]+0.01
}

for the addition case and

for (i in 1:50){
    M[which(M>min)] <- M[which(M>min)]-0.01
}

for the subtraction case.

Upvotes: 2

MrFlick
MrFlick

Reputation: 206253

How about a clip function

clip<-function(x, min=0, max=1) {
    x[x<min]<-min; 
    x[x>max]<-max; 
    x
}

This will set all values < min to the min, and all values > max to max. So if you subtract .9 from every cell, you expect a lot of negatives, but clip will change those to 0's

 clip(M-.9)

same goes for adding .9

 clip(M+.9)

Or was the problem that you were trying to subtract of the min? When doing something like

for (i in 1:50){
    M[,]<-M[,]-0.01
}

That statement inside the loop is operating on every element of the vector each time. So you're really subtracting off 0.5. Which is probably too much.

Upvotes: 0

Related Questions