[R] putting NAs at the end

Angel angel_lul at hotmail.com
Thu Aug 14 12:18:51 CEST 2003

```I'm afraid that's not what I wanted. Let's see if taking your example data I
can explain better.
Starting from:
>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
> [1,] 11.1 11.2 11.3 12.1 12.2 12.3 13.1 13.2 13.3  14.1  14.2  14.3
> [2,] 21.1 21.2   NA 22.1 22.2 22.3 23.1 23.2   NA  24.1  24.2  24.3
> [3,] 31.1 31.2 31.3 32.1 32.2 32.3 33.1 33.2 33.3  34.1  34.2  34.3
> [4,] 41.1 41.2 41.3 42.1 42.2 42.3 43.1 43.2 43.3  44.1  44.2  44.3
> [5,] 51.1 51.2 51.3 52.1 52.2   NA 53.1 53.2 53.3  54.1  54.2    NA
> [6,] 61.1 61.2 61.3 62.1 62.2 62.3 63.1 63.2 63.3  64.1  64.2  64.3
I want to arrive to:
>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
> [1,] 11.1 11.2 11.3 12.1 12.2 12.3 13.1 13.2 13.3  14.1  14.2  14.3
> [2,] 22.1 22.2 22.3 24.1  24.2  24.3 21.1 21.2   NA 23.1 23.2   NA
> [3,] 31.1 31.2 31.3 32.1 32.2 32.3 33.1 33.2 33.3  34.1  34.2  34.3
> [4,] 41.1 41.2 41.3 42.1 42.2 42.3 43.1 43.2 43.3  44.1  44.2  44.3
> [5,] 51.1 51.2 51.3 53.1 53.2 53.3  52.1 52.2   NA 54.1  54.2    NA
> [6,] 61.1 61.2 61.3 62.1 62.2 62.3 63.1 63.2 63.3  64.1  64.2  64.3
That is, for the second row the elements in columns 1:3 and 7:9 have moved
to the columns 7:9 and 10:12 and the rest of elements that were in 4:6 and
10:12 have moved to columns 1:3 and 4:6 respectively.
For row 5 the elements in columns 4:6 have moved to 7:9 and elements in
10:12 have "moved" to 10:12 and the elements in columns 7:9 take the columsn
4:6
For the rest of rows all the elements remain in the same position.
This is what my (slow) function does in a very rudimentary form:
----
I have a matrix for which each row has 12 elements that represent the xyz
coordinates of 4 points.
So each row of M is (x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4). Some points have
NA as z values.
I want another matrix to be the same as M but with the coordinates of those
points with z=NA placed last.
For ezample if z1=NA then the new matrix row should be
(x2,y2,z2,x3,y3,z3,x4,y4,z4,x1,y1,z1)
I've tried writing a function that does the job for each row and then apply
to the matrix

Put.NaN.last<-function(p) {
Index<-c(which(!is.na(p[c(3,6,9,12)]))*3,which(is.na(p[c(3,6,9,12)]))*3)
p<-c(p[Index[1]-2],p[Index[1]-1],p[Index[1]],
p[Index[2]-2],p[Index[2]-1],p[Index[2]],
p[Index[3]-2],p[Index[3]-1],p[Index[3]],
p[Index[4]-2],p[Index[4]-1],p[Index[4]])
return(p)
}
A<-matrix(1:36,ncol=12)
A[c(7,9,17,36)]<-NA
A<-t(apply(A,1,Put.NaN.last))

but it is awfully slow.
Any suggestions on how to do this faster?
Thanks
Angel
----

Hope it is clearer now. Thanks,
Angel

----- Original Message -----
From: "Ted Harding" <Ted.Harding at nessie.mcc.ac.uk>
To: "Angel" <angel_lul at hotmail.com>
Cc: <r-help at stat.math.ethz.ch>
Sent: Thursday, August 14, 2003 11:20 AM
Subject: Re: [R] putting NAs at the end

> Hi Angel,
> On 14-Aug-03 Angel wrote:
> > Yes, I have. I am sorry if I am missing some very basic stuff, but both
> > order and sort will not only put the NAs at the end (with na.last=TRUE)
> > BUT also sort in ascending or descending order the rest of the
> > elements and that is not what I want. And with order I would only get
> > the z NAs at the end and not also the associated x and y coordinates.
>
> This may not be the best way to do it, but it works and, I think, does
> what you want (and, in particular, preserves the original row order
> within the NA and non-NA blocks):
>
> Setup: First, a matrix x:
> > x
>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
> [1,] 11.1 11.2 11.3 12.1 12.2 12.3 13.1 13.2 13.3  14.1  14.2  14.3
> [2,] 21.1 21.2 21.3 22.1 22.2 22.3 23.1 23.2 23.3  24.1  24.2  24.3
> [3,] 31.1 31.2 31.3 32.1 32.2 32.3 33.1 33.2 33.3  34.1  34.2  34.3
> [4,] 41.1 41.2 41.3 42.1 42.2 42.3 43.1 43.2 43.3  44.1  44.2  44.3
> [5,] 51.1 51.2 51.3 52.1 52.2 52.3 53.1 53.2 53.3  54.1  54.2  54.3
> [6,] 61.1 61.2 61.3 62.1 62.2 62.3 63.1 63.2 63.3  64.1  64.2  64.3
>
> Setup: Next, set some NAs:
> > x1<-x;x1[2,3]<-NA;x1[2,9]<-NA;x1[5,6]<-NA;x1[5,12]<-NA;x1
>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
> [1,] 11.1 11.2 11.3 12.1 12.2 12.3 13.1 13.2 13.3  14.1  14.2  14.3
> [2,] 21.1 21.2   NA 22.1 22.2 22.3 23.1 23.2   NA  24.1  24.2  24.3
> [3,] 31.1 31.2 31.3 32.1 32.2 32.3 33.1 33.2 33.3  34.1  34.2  34.3
> [4,] 41.1 41.2 41.3 42.1 42.2 42.3 43.1 43.2 43.3  44.1  44.2  44.3
> [5,] 51.1 51.2 51.3 52.1 52.2   NA 53.1 53.2 53.3  54.1  54.2    NA
> [6,] 61.1 61.2 61.3 62.1 62.2 62.3 63.1 63.2 63.3  64.1  64.2  64.3
>
> The work: Now you want rows 2 and 5 at the end (if I understand):
> > icol<-c(3,6,9,12)
> > iNA<-is.na(rowSums(x1[,icol]))
> > x2<-x1[!iNA,]
> > x3<-x1[iNA,]
> > x4<-rbind(x2,x3);x4
>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
> [1,] 11.1 11.2 11.3 12.1 12.2 12.3 13.1 13.2 13.3  14.1  14.2  14.3
> [2,] 31.1 31.2 31.3 32.1 32.2 32.3 33.1 33.2 33.3  34.1  34.2  34.3
> [3,] 41.1 41.2 41.3 42.1 42.2 42.3 43.1 43.2 43.3  44.1  44.2  44.3
> [4,] 61.1 61.2 61.3 62.1 62.2 62.3 63.1 63.2 63.3  64.1  64.2  64.3
> [5,] 21.1 21.2   NA 22.1 22.2 22.3 23.1 23.2   NA  24.1  24.2  24.3
> [6,] 51.1 51.2 51.3 52.1 52.2   NA 53.1 53.2 53.3  54.1  54.2    NA
>
> The above five lines of code could make a function for your task.
> Is this OK?
> Best wishes,
> Ted.
>
>
> --------------------------------------------------------------------
> E-Mail: (Ted Harding) <Ted.Harding at nessie.mcc.ac.uk>
> Fax-to-email: +44 (0)870 167 1972
> Date: 14-Aug-03                                       Time: 10:20:20
> ------------------------------ XFMail ------------------------------
>

```