elements in each row of a matrix to the left.
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 intend...{{dropped}}