Re: [R] elements in each row of a matrix to the left.

From: Patrick Burns <pburns_at_pburns.seanet.com>
Date: Tue 28 Feb 2006 - 21:27:45 EST

Okay, I think this does the requested operation:

 > single.shift
function (x)
{

        r <- rle(is.na(x))
        if(!r$values[1]) return(x)
        num <- r$length[1]
        c(x[-1:-num], rep(NA, num))

}
 > t(apply(z, 1, single.shift))

john.gavin@ubs.com wrote:

>Hi Patrick/Jeff,
>
>
>
>>Does
>>
>>t(apply(z, 1, sort, na.last=TRUE))
>>
>>do what you want?
>>
>>
>
>Not quite.
>
>t(apply(z, 1, sort, na.last=TRUE))
>
> [,1] [,2] [,3]
>[1,] 1 1 NA
>[2,] 1 1 NA
>[3,] 1 1 NA
>[4,] 1 NA NA
>[5,] 1 NA NA
>[6,] NA NA NA
>
>Row 2 is the problem.
>
>I dont want to move all NAs to the end of each row.
>I just want to move all of the NAs before the first non-NA element,
>if any, to the end of each row.
>So in my example, rows 1 and 2 should remain unchanged.
>
>What I have got at the moment is ugly
>
>shiftLeft <- function(z)
>{ x <- as.data.frame(t(z)) # work with cols not rows.
> ans <- lapply(x, function(xx)
> { # get indices of first and last non-NA element
> ind <- which(!is.na(xx))
> ind <- ind[c(1, length(ind))]
> # if all NAs or if first element is non-NA do no work
> if (any(is.na(ind)) || ind[1] == 1) xx else
> { temp <- numeric(length(xx)) ; temp[] <- NA
> # move elements in posns ind[1] to ind[2] to the start
> temp[1:(ind[2]-ind[1]+1)] <- xx[ind[1]:ind[2]]
> temp
> } # if
> }) # lapply
> ans <- as.matrix(data.frame(ans))
> dimnames(ans) <- dimnames(z)
> t(ans)
>}
>
>
>
>>z ; shiftLeft(z)
>>
>>
> [,1] [,2] [,3]
>[1,] 1 1 NA
>[2,] 1 NA 1
>[3,] NA 1 1
>[4,] NA NA 1
>[5,] NA 1 NA
>[6,] NA NA NA
> [,1] [,2] [,3]
>[1,] 1 1 NA
>[2,] 1 NA 1
>[3,] 1 1 NA
>[4,] 1 NA NA
>[5,] 1 NA NA
>[6,] NA NA NA
>
>I feel that there is probably a shorter vectorised way to do this.
>In general, I have matrices (z) with several thousand rows and
>and few hundred columns so vectorisation would help.
>
>Regards,
>
>John.
>
>
>
>
>>-----Original Message-----
>>From: Patrick Burns [mailto:pburns@pburns.seanet.com]
>>Sent: 27 February 2006 19:55
>>To: Gavin, John
>>Cc: r-help@stat.math.ethz.ch
>>Subject: Re: [R] elements in each row of a matrix to the left.
>>
>>John,
>>
>>Does
>>
>>t(apply(z, 1, sort, na.last=TRUE))
>>
>>do what you want?
>>
>>
>>Patrick Burns
>>patrick@burns-stat.com
>>+44 (0)20 8525 0696
>>http://www.burns-stat.com
>>(home of S Poetry and "A Guide for the Unwilling S User")
>>
>>john.gavin@ubs.com wrote:
>>
>>
>>
>>>Hi,
>>>
>>>Given a matrix like
>>>
>>>(z <- matrix(c(
>>>1, 1, NA, NA, NA, NA,
>>>1, NA, 1, NA, 1, NA,
>>>NA, 1, 1, 1, NA, NA), ncol = 3))
>>>
>>> [,1] [,2] [,3]
>>>[1,] 1 1 NA
>>>[2,] 1 NA 1
>>>[3,] NA 1 1
>>>[4,] NA NA 1
>>>[5,] NA 1 NA
>>>[6,] NA NA NA
>>>
>>>is there a vectorised way to produce the output like
>>>
>>> [,1] [,2] [,3]
>>>[1,] 1 1 NA
>>>[2,] 1 NA 1
>>>[3,] 1 1 NA
>>>[4,] 1 NA NA
>>>[5,] 1 NA NA
>>>[6,] NA NA NA
>>>
>>>That is, given an n by m matrix, and going row by row,
>>>if the first non-NA element is in column k
>>>I want to move elements in columns from k to m
>>>to columns 1 to m-k+1 with NAs filling in from
>>>m-k+2 to m.
>>>
>>>
>>>
>>>
>>>
>>>>version
>>>>
>>>>
>>>>
>>>>
>>> _
>>>platform i386-pc-mingw32
>>>arch i386
>>>os mingw32
>>>system i386, mingw32
>>>status
>>>major 2
>>>minor 2.1
>>>year 2005
>>>month 12
>>>day 20
>>>svn rev 36812
>>>language R
>>>
>>>Regards,
>>>
>>>John.
>>>
>>>John Gavin <john.gavin@ubs.com>,
>>>Quantitative Risk Control,
>>>UBS Investment Bank, 6th floor,
>>>100 Liverpool St., London EC2M 2RH, UK.
>>>Phone +44 (0) 207 567 4289
>>>Fax +44 (0) 207 568 5352
>>>
>>>Visit our website at http://www.ubs.com
>>>
>>>This message contains confidential information and is
>>>
>>>
>>intend...{{dropped}}
>>
>>
>>>______________________________________________
>>>R-help@stat.math.ethz.ch mailing list
>>>https://stat.ethz.ch/mailman/listinfo/r-help
>>>PLEASE do read the posting guide!
>>>
>>>
>http://www.R-project.org/posting-guide.html
>
>
>>
>>
>>
>>
>>
>
>
>Visit our website at http://www.ubs.com
>
>This message contains confidential information and is intended only
>for the individual named. If you are not the named addressee you
>should not disseminate, distribute or copy this e-mail. Please
>notify the sender immediately by e-mail if you have received this
>e-mail by mistake and delete this e-mail from your system.
>
>E-mail transmission cannot be guaranteed to be secure or error-free
>as information could be intercepted, corrupted, lost, destroyed,
>arrive late or incomplete, or contain viruses. The sender therefore
>does not accept liability for any errors or omissions in the contents
>of this message which arise as a result of e-mail transmission. If
>verification is required please request a hard-copy version. This
>message is provided for informational purposes and should not be
>construed as a solicitation or offer to buy or sell any securities or
>related financial instruments.
>
>
>
>
>
>



R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html Received on Tue Feb 28 21:44:09 2006

This archive was generated by hypermail 2.1.8 : Fri 03 Mar 2006 - 03:42:47 EST