[R] [ifelse] how to maintain a value from original matrix without probs?
Marc Schwartz
marc_schwartz at comcast.net
Fri Oct 31 18:09:12 CET 2008
on 10/31/2008 09:59 AM Diogo André Alagador wrote:
> Dear all,
>
> I have a matrix with positive and negative values.
>>From this I would like to produce 2 matrices:
> 1st - retaining positives and putting NA in other positions
> 2nd - retaining negatives and putting NA in other positions
>
> and then apply rowMeans for both.
>
> I am trying to use the function ifelse in the exemplified form:
> ifelse(A>0,A,NA)
> but by putting A as a 2nd parameter it changes dimensions of the original
> object.
>
> I wonder if I can do this, as it seems not to difficult.
>
> thanks in advance
A couple of approaches, depending upon the size of the matrix.
The first, if the matrix is "small-ish":
set.seed(1)
mat <- matrix(sample(-10:10, 100, replace = TRUE), ncol = 10)
> mat
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] -5 -6 9 0 7 0 9 -3 -1 -5
[2,] -3 -7 -6 2 3 8 -4 7 4 -9
[3,] 2 4 3 0 6 -1 -1 -3 -2 3
[4,] 9 -2 -8 -7 1 -5 -4 -3 -4 8
[5,] -6 6 -5 7 1 -9 3 0 5 6
[6,] 8 0 -2 4 6 -8 -5 8 -6 6
[7,] 9 5 -10 6 -10 -4 0 8 4 -1
[8,] 3 10 -2 -8 0 0 6 -2 -8 -2
[9,] 3 -3 8 5 5 3 -9 6 -5 7
[10,] -9 6 -3 -2 4 -2 8 10 -7 2
> apply(mat, 1, function(x) mean(x[x > 0], na.rm = TRUE))
[1] 8.333333 4.800000 3.600000 6.000000 4.666667 6.400000 6.400000
[8] 6.333333 5.285714 6.000000
> apply(mat, 1, function(x) mean(x[x < 0], na.rm = TRUE))
[1] -4.000000 -5.800000 -1.750000 -4.714286 -6.666667 -5.250000
[7] -6.250000 -4.400000 -5.666667 -4.600000
This way, you avoid splitting the matrix. You did not specify how you
might want 0's to be handled, so adjust the logic above accordingly.
If the matrix is large, such that that splitting it and using rowMeans()
would be faster:
mat.pos <- mat
is.na(mat.pos) <- mat <= 0
> mat.pos
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] NA NA 9 NA 7 NA 9 NA NA NA
[2,] NA NA NA 2 3 8 NA 7 4 NA
[3,] 2 4 3 NA 6 NA NA NA NA 3
[4,] 9 NA NA NA 1 NA NA NA NA 8
[5,] NA 6 NA 7 1 NA 3 NA 5 6
[6,] 8 NA NA 4 6 NA NA 8 NA 6
[7,] 9 5 NA 6 NA NA NA 8 4 NA
[8,] 3 10 NA NA NA NA 6 NA NA NA
[9,] 3 NA 8 5 5 3 NA 6 NA 7
[10,] NA 6 NA NA 4 NA 8 10 NA 2
> rowMeans(mat.pos, na.rm = TRUE)
[1] 8.333333 4.800000 3.600000 6.000000 4.666667 6.400000 6.400000
[8] 6.333333 5.285714 6.000000
mat.neg <- mat
is.na(mat.neg) <- mat >= 0
> mat.neg
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] -5 -6 NA NA NA NA NA -3 -1 -5
[2,] -3 -7 -6 NA NA NA -4 NA NA -9
[3,] NA NA NA NA NA -1 -1 -3 -2 NA
[4,] NA -2 -8 -7 NA -5 -4 -3 -4 NA
[5,] -6 NA -5 NA NA -9 NA NA NA NA
[6,] NA NA -2 NA NA -8 -5 NA -6 NA
[7,] NA NA -10 NA -10 -4 NA NA NA -1
[8,] NA NA -2 -8 NA NA NA -2 -8 -2
[9,] NA -3 NA NA NA NA -9 NA -5 NA
[10,] -9 NA -3 -2 NA -2 NA NA -7 NA
> rowMeans(mat.neg, na.rm = TRUE)
[1] -4.000000 -5.800000 -1.750000 -4.714286 -6.666667 -5.250000
[7] -6.250000 -4.400000 -5.666667 -4.600000
See ?is.na and note the assignment variant.
HTH,
Marc Schwartz
More information about the R-help
mailing list