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

Patrick Burns pburns at pburns.seanet.com
Tue Feb 28 11:27:45 CET 2006


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 at 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 at pburns.seanet.com]
>>Sent: 27 February 2006 19:55
>>To: Gavin, John
>>Cc: r-help at 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 at 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 at 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 at 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 at 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.
>
>
>
>
>  
>




More information about the R-help mailing list