[R] efficient way to replace a range of numeric with a integer in a matrix
David Winsemius
dwinsemius at comcast.net
Tue Aug 12 01:49:33 CEST 2014
On Aug 11, 2014, at 3:27 PM, Jinsong Zhao wrote:
> On 2014/8/11 14:50, William Dunlap wrote:
>> You can use
>> m[m > 0 & m <= 1.0] <- 1
>> m[m > 1 ] <- 2
>> or, if you have lots of intervals, something based on findInterval(). E.g.,
>> m[] <- findInterval(m, c(-Inf, 0, 1, Inf)) - 1
>>
OR, if you have irregularly spaced intervals or particular values to match to the intervals, you can use findInterval to define categories and select with "[":
> set.seed(42); m <- matrix( rnorm(100, 10, 5), 10)
> round( m, 2)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 16.85 16.52 8.47 12.28 11.03 11.61 8.16 4.78 17.56 16.96
[2,] 7.18 21.43 1.09 13.52 8.19 6.08 10.93 9.55 11.29 7.62
[3,] 11.82 3.06 9.14 15.18 13.79 17.88 12.91 13.12 10.44 13.25
[4,] 13.16 8.61 16.07 6.96 6.37 13.21 17.00 5.23 9.40 16.96
[5,] 12.02 9.33 19.48 12.52 3.16 10.45 6.36 7.29 4.03 4.45
[6,] 9.47 13.18 7.85 1.41 12.16 11.38 16.51 12.90 13.06 5.70
[7,] 17.56 8.58 8.71 6.08 5.94 13.40 11.68 13.84 8.91 4.34
[8,] 9.53 -3.28 1.18 5.75 17.22 10.45 15.19 12.32 9.09 2.70
[9,] 20.09 -2.20 12.30 -2.07 7.84 -4.97 14.60 5.57 14.67 10.40
[10,] 9.69 16.60 6.80 10.18 13.28 11.42 13.60 4.50 14.11 13.27
> m[] <- c(1,2,4,8,16, 32) [ findInterval(m, c(-Inf, 2, 5, 10, 15, 18, Inf) ) ]
> m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 16 16 4 8 8 8 4 2 16 16
[2,] 4 32 1 8 4 4 8 4 8 4
[3,] 8 2 4 16 8 16 8 8 8 8
[4,] 8 4 16 4 4 8 16 4 4 16
[5,] 8 4 32 8 2 8 4 4 2 2
[6,] 4 8 4 1 8 8 16 8 8 4
[7,] 16 4 4 4 4 8 8 8 4 2
[8,] 4 1 1 4 16 8 16 8 4 2
[9,] 32 1 8 1 4 1 8 4 8 8
[10,] 4 16 4 8 8 8 8 2 8 8
--
David.
>> (What do you want to do with non-positive numbers?)
>>
>> Bill Dunlap
>> TIBCO Software
>> wdunlap tibco.com
>
> Thank you very much.
>
> I think findInterval() is what I want.
>
> Regards,
> Jinsong
>
>>
>>
>> On Mon, Aug 11, 2014 at 2:40 PM, Jinsong Zhao <jszhao at yeah.net> wrote:
>>> Hi there,
>>>
>>> I hope to replace a range of numeric in a matrix with a integer. For
>>> example, in the following matrix, I want to use 1 to replace the elements
>>> range from 0.0 to 1.0, and all larger than 1. with 2.
>>>
>>>> (m <- matrix(runif(16, 0, 2), nrow = 4))
>>> [,1] [,2] [,3] [,4]
>>> [1,] 0.7115088 0.55370418 0.1586146 1.882931
>>> [2,] 0.9068198 0.38081423 0.9172629 1.713592
>>> [3,] 1.5210150 0.93900649 1.2609942 1.744456
>>> [4,] 0.3779058 0.03130103 0.1893477 1.601181
>>>
>>> so I want to get something like:
>>>
>>> [,1] [,2] [,3] [,4]
>>> [1,] 1 1 1 2
>>> [2,] 1 1 1 2
>>> [3,] 2 1 2 2
>>> [4,] 1 1 1 2
>>>
>>> I wrote a function to do such thing:
>>>
>>> fun <- function(x) {
>>> if (is.na(x)) {
>>> NA
>>> } else if (x > 0.0 && x <= 1.0) {
>>> 1
>>> } else if (x > 1.0) {
>>> 2
>>> } else {
>>> x
>>> }
>>> }
>>>
>>> Then run it as:
>>>
>>>> apply(m,2,function(i) sapply(i, fun))
>>>
>>> However, it seems that this method is not efficient when the dimension is
>>> large, e.g., 5000x5000 matrix.
>>>
>>> Any suggestions? Thanks in advance!
>>>
>>> Best regards,
>>> Jinsong
>
David Winsemius
Alameda, CA, USA
More information about the R-help
mailing list