[R] how to skip a specific value when using apply() function to a matrix?

Shuhua Zhan szhan at uoguelph.ca
Fri Jul 16 22:46:55 CEST 2010


Hello Joshua and Wu,
Thank you for your excellent solutions.
Joshua 
----- Original Message -----
From: "Joshua Wiley" <jwiley.psych at gmail.com>
To: "Shuhua Zhan" <szhan at uoguelph.ca>
Cc: r-help at r-project.org
Sent: Friday, July 16, 2010 12:39:22 PM GMT -05:00 US/Canada Eastern
Subject: Re: [R] how to skip a specific value when using apply() function to a  matrix?

Hello,

This does what you want.  The simple solution is shorter but requires
that there is only one value you wish to exclude (e.g., 0).  The
second works for any number of values you wish to exclude, but is
subsequently longer.  Also there is no need to create your own
function to 'studentize', ?scale will do it for you (as well as simply
center), this has the added benefit of not needing to convert the
results of apply() back to a matrix.

##Create data##
tmp1 <- structure(c(15L, 13L, 10L, 15L, 12L, 11L, 7L, 7L, 2L, 5L, 9L,
12L, 9L, 10L, 12L, 30L, 71L, 2L, 49L, 56L, 50L, 52L, 76L, 69L,
60L, 21L, 19L, 120L, 211L, 18L, 3L, 4L, 1L, 2L, 4L, 5L, 2L, 3L,
0L, 4L, 3L, 2L, 0L, 0L, 2L, 0L, 1L, 0L), .Dim = c(6L, 8L))

tmp2 <- tmp1 #for use in second solution

##Simple Solution##

tmp1[tmp1 == 0] <- NA #change 0s to NAs
tmp1 <- apply(tmp1, 2, scale) # 'studentize'
tmp1[is.na(tmp1)] <- 0 #change NAs back to 0s

##More General Solution##

#Stores positions of 0s and 1s in origianl matrix
positions <- which(tmp2 == 0 | tmp2 == 1)

#Store original values at 'positions'
replacements <- tmp2[positions]

#Change these to NAs
tmp2[positions] <- NA

#Scale using NAs
tmp2 <- apply(tmp2, 2, scale)

#Now replace the NAs with the origianl values
tmp2[positions] <- replacements

#Print to screen
tmp1
tmp2

HTH,

Josh

On Fri, Jul 16, 2010 at 9:11 AM, Shuhua Zhan <szhan at uoguelph.ca> wrote:
> Hello Nikhil and Wu,
> Thank you very much for your reply!
> What I want is to calculate the student's score column-wise by ignoring the specific values such as zeros for example only using c(2,1) in column 8 in the tmp1 and generate tmp2. I changed the zeros to NAs and modified my stud fun to student as below. So I can ignore these specific values but can not put back the NAs to the right position in the resulted matrix.
> Any suggestions to put back NAs to their original positions in column 7 and 8 either to list tmp4 or matrix tmp5?
>
> tmp1[tmp1==0]<-NA
> student<- function(x){
>    x<-x[!is.na(x)]
>    x<-(x-mean(x))/sd(x)
>    return (x)
> }
> tmp4<-apply(tmp1, 2, student)
> tmp4
> [[1]]
> [1]  1.1296201  0.1613743 -1.2909944  1.1296201 -0.3227486 -0.8068715
>
> [[2]]
> [1]  0.0000000  0.0000000 -1.4680505 -0.5872202  0.5872202  1.4680505
>
> [[3]]
> [1] -0.5207910 -0.4817316 -0.4036130  0.2994548  1.9008870 -0.7942062
>
> [[4]]
> [1] -0.8630035 -0.2380699 -0.7737273 -0.5951748  1.5474546  0.9225210
>
> [[5]]
> [1] -0.1913482 -0.6944435 -0.7202433  0.5826446  1.7565336 -0.7331431
>
> [[6]]
> [1] -0.1132277  0.5661385 -1.4719601 -0.7925939  0.5661385  1.2455047
>
> [[7]]
> [1] -0.9561829  0.2390457  1.4342743  0.2390457 -0.9561829
>
> [[8]]
> [1]  0.7071068 -0.7071068
>
> tmp5<- matrix(unlist(tmp4),nrow=6)
> tmp5
>           [,1]       [,2]       [,3]       [,4]       [,5]       [,6]       [,7]       [,8]
> [1,]  1.1296201  0.0000000 -0.5207910 -0.8630035 -0.1913482 -0.1132277 -0.9561829 -0.7071068
> [2,]  0.1613743  0.0000000 -0.4817316 -0.2380699 -0.6944435  0.5661385  0.2390457  1.1296201
> [3,] -1.2909944 -1.4680505 -0.4036130 -0.7737273 -0.7202433 -1.4719601  1.4342743  0.1613743
> [4,]  1.1296201 -0.5872202  0.2994548 -0.5951748  0.5826446 -0.7925939  0.2390457 -1.2909944
> [5,] -0.3227486  0.5872202  1.9008870  1.5474546  1.7565336  0.5661385 -0.9561829  1.1296201
> [6,] -0.8068715  1.4680505 -0.7942062  0.9225210 -0.7331431  1.2455047  0.7071068 -0.3227486
>
> Joshua
>
> ----- Original Message -----
> From: "Shuhua Zhan" <szhan at uoguelph.ca>
> To: r-help at r-project.org
> Sent: Thursday, July 15, 2010 11:08:34 PM GMT -05:00 US/Canada Eastern
> Subject: [R] how to skip a specific value when using apply() function to a matrix?
>
> Hello R experts,
> I'd like to studentize a matrix (tmp1) by column using apply() function and skip some specific values such as zeros in the example below to tmp2 but not tmp3. I used the script below and only can get a matrix tmp3. Could you please help me to studentize the matrix (tmp1) without changing the zeros and generate a new matrix tmp2?
> Thanks,
> Joshua
>
> tmp1
>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
> [1,]   15    7    9   49   60    3    2    0
> [2,]   13    7   10   56   21    4    3    0
> [3,]   10    2   12   50   19    1    0    2
> [4,]   15    5   30   52  120    2    4    0
> [5,]   12    9   71   76  211    4    3    1
> [6,]   11   12    2   69   18    5    2    0
>
> tmp2
> [1,]  1.1296201  0.0000000 -0.5207910 -0.8630035 -0.1913482 -0.1132277 -0.9561829  0.0000000
> [2,]  0.1613743  0.0000000 -0.4817316 -0.2380699 -0.6944435  0.5661385  0.2390457  0.0000000
> [3,] -1.2909944 -1.4680505 -0.4036130 -0.7737273 -0.7202433 -1.4719601  0.0000000  0.7071068
> [4,]  1.1296201 -0.5872202  0.2994548 -0.5951748  0.5826446 -0.7925939  1.4342743  0.0000000
> [5,] -0.3227486  0.5872202  1.9008870  1.5474546  1.7565336  0.5661385  0.2390457 -0.7071068
> [6,] -0.8068715  1.4680505 -0.7942062  0.9225210 -0.7331431  1.2455047 -0.9561829  0.0000000
>
> tmp3
>          [,1]       [,2]       [,3]       [,4]       [,5]       [,6]      [,7]       [,8]
> [1,]  1.1296201  0.0000000 -0.5207910 -0.8630035 -0.1913482 -0.1132277 -0.243975 -0.5976143
> [2,]  0.1613743  0.0000000 -0.4817316 -0.2380699 -0.6944435  0.5661385  0.487950 -0.5976143
> [3,] -1.2909944 -1.4680505 -0.4036130 -0.7737273 -0.7202433 -1.4719601 -1.707825  1.7928429
> [4,]  1.1296201 -0.5872202  0.2994548 -0.5951748  0.5826446 -0.7925939  1.219875 -0.5976143
> [5,] -0.3227486  0.5872202  1.9008870  1.5474546  1.7565336  0.5661385  0.487950  0.5976143
> [6,] -0.8068715  1.4680505 -0.7942062  0.9225210 -0.7331431  1.2455047 -0.243975 -0.5976143
>
> Here is my script:
> stud<- function(x){
>    x<-(x-mean(x))/sd(x)
>    return (x)
> }
> tmp3<-apply(tmp1,2,stud)
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>



-- 
Joshua Wiley
Ph.D. Student, Health Psychology
University of California, Los Angeles
http://www.joshuawiley.com/



More information about the R-help mailing list