[R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
Hi, I'm trying to take a matrix such as [,1] [,2] [,3] [,4] [,5] [1,]27279 [2,] 10 10686 [3,]19720 and generate a new matrix which contains only the unique values in each row: [,1] [,2] [,3] [,4] [,5] [1,]279 NA NA [2,] 1068 NA NA [3,]19720 My problem is that I can use apply(matrix,MARGIN=1,FUN=unique) to find the unique values, but this leaves me with a list with arrays of different length: > x <- apply(peaks,MARGIN=1,FUN=unique) [[1]] [1] 2 7 9 [[2]] [1] 10 6 8 [[3]] [1] 1 9 7 2 0 and using do.call("rbind",x) recycles the values of the shorter vectors instead of filling them with NA: > do.call("rbind",x) [,1] [,2] [,3] [,4] [,5] [1,]27927 [2,] 1068 106 [3,]19720 So, I'd like to either take every element of the list and extend it with NAs to the length of the longest element, or rbind every element where missing places are filled with NAs instead of recycled values. Is this possible? Of course, the solution is trivial using a loop, but I'm trying to avoid this. Thanks for any suggestions. __ R-help@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
Dear Jason, Try this: x<-matrix(scan(),byrow=TRUE,ncol=5) 27279 10 10686 19720 res<-apply(x,1,unique) # Unique values maxlength<-max(do.call(c,lapply(res,length))) # Maximum length of unique values # Your matrix do.call(rbind,lapply(res,function(x){ x[maxlength]<-NA x } ) ) HTH, Jorge On Thu, Feb 12, 2009 at 2:31 PM, Jason Shaw wrote: > Hi, > > I'm trying to take a matrix such as > > [,1] [,2] [,3] [,4] [,5] > [1,]27279 > [2,] 10 10686 > [3,]19720 > > and generate a new matrix which contains only the unique values in each > row: > > [,1] [,2] [,3] [,4] [,5] > [1,]279 NA NA > [2,] 1068 NA NA > [3,]19720 > > My problem is that I can use apply(matrix,MARGIN=1,FUN=unique) to find > the unique values, but this leaves me with a list with arrays of > different length: > > > x <- apply(peaks,MARGIN=1,FUN=unique) > [[1]] > [1] 2 7 9 > > [[2]] > [1] 10 6 8 > > [[3]] > [1] 1 9 7 2 0 > > and using do.call("rbind",x) recycles the values of the shorter > vectors instead of filling them with NA: > > > do.call("rbind",x) > [,1] [,2] [,3] [,4] [,5] > [1,]27927 > [2,] 1068 106 > [3,]19720 > > So, I'd like to either take every element of the list and extend it > with NAs to the length of the longest element, or rbind every element > where missing places are filled with NAs instead of recycled values. > Is this possible? Of course, the solution is trivial using a loop, > but I'm trying to avoid this. > > Thanks for any suggestions. > > __ > R-help@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. > [[alternative HTML version deleted]] __ R-help@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
Try this. After the apply from your post we use lapply to make each series into a zoo series so that we can later use zoo's multiway merge. Finally we actually merge them and in the next statement just makes nice column names: > library(zoo) > all3 <- do.call(merge, lapply(apply(peaks, 1, unique), zoo)) > colnames(all3) <- make.names(1:ncol(all3)) > all3 X1 X2 X3 1 2 10 1 2 7 6 9 3 9 8 7 4 NA NA 2 5 NA NA 0 On Thu, Feb 12, 2009 at 2:31 PM, Jason Shaw wrote: > Hi, > > I'm trying to take a matrix such as > > [,1] [,2] [,3] [,4] [,5] > [1,]27279 > [2,] 10 10686 > [3,]19720 > > and generate a new matrix which contains only the unique values in each row: > > [,1] [,2] [,3] [,4] [,5] > [1,]279 NA NA > [2,] 1068 NA NA > [3,]19720 > > My problem is that I can use apply(matrix,MARGIN=1,FUN=unique) to find > the unique values, but this leaves me with a list with arrays of > different length: > >> x <- apply(peaks,MARGIN=1,FUN=unique) > [[1]] > [1] 2 7 9 > > [[2]] > [1] 10 6 8 > > [[3]] > [1] 1 9 7 2 0 > > and using do.call("rbind",x) recycles the values of the shorter > vectors instead of filling them with NA: > >> do.call("rbind",x) > [,1] [,2] [,3] [,4] [,5] > [1,]27927 > [2,] 1068 106 > [3,]19720 > > So, I'd like to either take every element of the list and extend it > with NAs to the length of the longest element, or rbind every element > where missing places are filled with NAs instead of recycled values. > Is this possible? Of course, the solution is trivial using a loop, > but I'm trying to avoid this. > > Thanks for any suggestions. > > __ > R-help@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@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
Hi Jason: below seems to work. you have to take the transpose because the apply returns the rows transposed. i'm also not sure how to make the NAs be the last ones but maybe someone can show us how to do that. mat <- matrix(c(2,7,2,7,9,10,10,6,8,6,1,9,7,2,0),byrow=TRUE,nrow=3) print(mat) t(apply(mat,1, function(.row) { .row[duplicated(.row)] <- NA .row })) On Thu, Feb 12, 2009 at 2:31 PM, Jason Shaw wrote: Hi, I'm trying to take a matrix such as [,1] [,2] [,3] [,4] [,5] [1,]27279 [2,] 10 10686 [3,]19720 and generate a new matrix which contains only the unique values in each row: [,1] [,2] [,3] [,4] [,5] [1,]279 NA NA [2,] 1068 NA NA [3,]19720 My problem is that I can use apply(matrix,MARGIN=1,FUN=unique) to find the unique values, but this leaves me with a list with arrays of different length: x <- apply(peaks,MARGIN=1,FUN=unique) [[1]] [1] 2 7 9 [[2]] [1] 10 6 8 [[3]] [1] 1 9 7 2 0 and using do.call("rbind",x) recycles the values of the shorter vectors instead of filling them with NA: do.call("rbind",x) [,1] [,2] [,3] [,4] [,5] [1,]27927 [2,] 1068 106 [3,]19720 So, I'd like to either take every element of the list and extend it with NAs to the length of the longest element, or rbind every element where missing places are filled with NAs instead of recycled values. Is this possible? Of course, the solution is trivial using a loop, but I'm trying to avoid this. Thanks for any suggestions. __ R-help@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@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
On 13/02/2009, at 9:06 AM, markle...@verizon.net wrote: Hi Jason: below seems to work. you have to take the transpose because the apply returns the rows transposed. i'm also not sure how to make the NAs be the last ones but maybe someone can show us how to do that. Pretty easy: na.at.end <- function(x){ i <- is.na(x) c(x[!i],rep(NA,sum(i))) } mat <- matrix(c(2,7,2,7,9,10,10,6,8,6,1,9,7,2,0),byrow=TRUE,nrow=3) print(mat) t(apply(mat,1, function(.row) { .row[duplicated(.row)] <- NA .row })) Then just change to: t(apply(mat,1, function(.row) { .row[duplicated(.row)] <- NA na.at.end(.row) })) cheers, Rolf ## Attention:\ This e-mail message is privileged and confid...{{dropped:9}} __ R-help@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
Thanks Rolf. very nice but "pretty easy" is ALWAYS a relative statement. On Thu, Feb 12, 2009 at 3:59 PM, Rolf Turner wrote: On 13/02/2009, at 9:06 AM, markle...@verizon.net wrote: Hi Jason: below seems to work. you have to take the transpose because the apply returns the rows transposed. i'm also not sure how to make the NAs be the last ones but maybe someone can show us how to do that. Pretty easy: na.at.end <- function(x){ i <- is.na(x) c(x[!i],rep(NA,sum(i))) } mat <- matrix(c(2,7,2,7,9,10,10,6,8,6,1,9,7,2,0),byrow=TRUE,nrow=3) print(mat) t(apply(mat,1, function(.row) { .row[duplicated(.row)] <- NA .row })) Then just change to: t(apply(mat,1, function(.row) { .row[duplicated(.row)] <- NA na.at.end(.row) })) cheers, Rolf ## Attention: This e-mail message is privileged and confidential. If you are not the intended recipient please delete the message and notify the sender. Any views or opinions presented are solely those of the author. This e-mail has been scanned and cleared by MailMarshal www.marshalsoftware.com ## __ R-help@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
markle...@verizon.net wrote: > Thanks Rolf. very nice but "pretty easy" is ALWAYS a relative statement. > right. it's even "easier": na.last = function(x) { na = is.na(x) c(x[!na], x[na]) } > > > On Thu, Feb 12, 2009 at 3:59 PM, Rolf Turner wrote: > >> On 13/02/2009, at 9:06 AM, markle...@verizon.net wrote: >> >>> Hi Jason: below seems to work. you have to take the transpose because >>> the apply >>> returns the rows transposed. i'm also not sure how to make the NAs be >>> the last >>> ones but maybe someone can show us how to do that. >> >> Pretty easy: >> >> na.at.end <- function(x){ >> i <- is.na(x) >> c(x[!i],rep(NA,sum(i))) >> } __ R-help@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
At the risk of beating the decaying skeletal remains of the stone dead horse, a one-liner: t(apply(mat,1,function(x)c(unique(x),rep(NA,sum(duplicated(x)) (probably more efficient as a 2-liner that calls duplicated/unique only once, though) -- Bert Gunter, Genentech -Original Message- From: r-help-boun...@r-project.org [mailto:r-help-boun...@r-project.org] On Behalf Of markle...@verizon.net Sent: Thursday, February 12, 2009 1:05 PM To: Rolf Turner Cc: r-help@r-project.org; Jason Shaw Subject: Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling Thanks Rolf. very nice but "pretty easy" is ALWAYS a relative statement. On Thu, Feb 12, 2009 at 3:59 PM, Rolf Turner wrote: > On 13/02/2009, at 9:06 AM, markle...@verizon.net wrote: > >> Hi Jason: below seems to work. you have to take the transpose because >> the apply >> returns the rows transposed. i'm also not sure how to make the NAs be >> the last >> ones but maybe someone can show us how to do that. > > Pretty easy: > > na.at.end <- function(x){ > i <- is.na(x) > c(x[!i],rep(NA,sum(i))) > } > >> >> mat <- matrix(c(2,7,2,7,9,10,10,6,8,6,1,9,7,2,0),byrow=TRUE,nrow=3) >> print(mat) >> >> t(apply(mat,1, function(.row) { >>.row[duplicated(.row)] <- NA >>.row >> })) > > Then just change to: > > t(apply(mat,1, function(.row) { >.row[duplicated(.row)] <- NA >na.at.end(.row) > })) > > cheers, > > Rolf > > ## > Attention: This e-mail message is privileged and confidential. If you > are not the intended recipient please delete the message and notify > the sender. Any views or opinions presented are solely those of the > author. > > This e-mail has been scanned and cleared by MailMarshal > www.marshalsoftware.com > ## __ R-help@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@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
Here is one other solution. Its nearly the same as the last but uses ts instead of zoo: > all3 <- do.call(cbind, lapply(apply(peaks, 1, unique), ts)) > colnames(all3) <- make.names(1:ncol(all3)) > all3 Time Series: Start = 1 End = 5 Frequency = 1 X1 X2 X3 1 2 10 1 2 7 6 9 3 9 8 7 4 NA NA 2 5 NA NA 0 or unclass(all3) if you don't want it as a ts object. (Similar comment for the zoo solution.) On Thu, Feb 12, 2009 at 3:16 PM, Gabor Grothendieck wrote: > Try this. After the apply from your post we use lapply > to make each series into a zoo series so that we can later > use zoo's multiway merge. Finally we actually merge them > and in the next statement just makes nice column names: > >> library(zoo) > >> all3 <- do.call(merge, lapply(apply(peaks, 1, unique), zoo)) >> colnames(all3) <- make.names(1:ncol(all3)) >> all3 > X1 X2 X3 > 1 2 10 1 > 2 7 6 9 > 3 9 8 7 > 4 NA NA 2 > 5 NA NA 0 > > > On Thu, Feb 12, 2009 at 2:31 PM, Jason Shaw wrote: >> Hi, >> >> I'm trying to take a matrix such as >> >> [,1] [,2] [,3] [,4] [,5] >> [1,]27279 >> [2,] 10 10686 >> [3,]19720 >> >> and generate a new matrix which contains only the unique values in each row: >> >> [,1] [,2] [,3] [,4] [,5] >> [1,]279 NA NA >> [2,] 1068 NA NA >> [3,]19720 >> >> My problem is that I can use apply(matrix,MARGIN=1,FUN=unique) to find >> the unique values, but this leaves me with a list with arrays of >> different length: >> >>> x <- apply(peaks,MARGIN=1,FUN=unique) >> [[1]] >> [1] 2 7 9 >> >> [[2]] >> [1] 10 6 8 >> >> [[3]] >> [1] 1 9 7 2 0 >> >> and using do.call("rbind",x) recycles the values of the shorter >> vectors instead of filling them with NA: >> >>> do.call("rbind",x) >> [,1] [,2] [,3] [,4] [,5] >> [1,]27927 >> [2,] 1068 106 >> [3,]19720 >> >> So, I'd like to either take every element of the list and extend it >> with NAs to the length of the longest element, or rbind every element >> where missing places are filled with NAs instead of recycled values. >> Is this possible? Of course, the solution is trivial using a loop, >> but I'm trying to avoid this. >> >> Thanks for any suggestions. >> >> __ >> R-help@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@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
G'day all, On Thu, 12 Feb 2009 14:06:21 -0600 (CST) markle...@verizon.net wrote: > Hi Jason: below seems to work. you have to take the transpose because > the apply > returns the rows transposed. i'm also not sure how to make the NAs be > the last > ones but maybe someone can show us how to do that. > > mat <- matrix(c(2,7,2,7,9,10,10,6,8,6,1,9,7,2,0),byrow=TRUE,nrow=3) > print(mat) > > t(apply(mat,1, function(.row) { >.row[duplicated(.row)] <- NA >.row > })) Alternatively to Rolf's solution for putting NAs at the end, if the order of the entries is not important, a sort(.row, na.last=TRUE) instead of Rolf's na.at.end(.row) would do the trick too. Yet another way would be to just search for the unique values, concatenate them with a (sufficiently long) vector of NAs and then shorten the result to the desired size: t(apply(mat, 1, function(r){ rl <- length(r) c(unique(r), rep(NA,rl))[1:rl] })) Cheers, Berwin __ R-help@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
My question is: Why would you want a data structure that is clearly not expressive of the data involved? Let me guess. You are coming from statistical software where data are always rectangular. Patrick Burns patr...@burns-stat.com +44 (0)20 8525 0696 http://www.burns-stat.com (home of "The R Inferno" and "A Guide for the Unwilling S User") Jason Shaw wrote: Hi, I'm trying to take a matrix such as [,1] [,2] [,3] [,4] [,5] [1,]27279 [2,] 10 10686 [3,]19720 and generate a new matrix which contains only the unique values in each row: [,1] [,2] [,3] [,4] [,5] [1,]279 NA NA [2,] 1068 NA NA [3,]19720 My problem is that I can use apply(matrix,MARGIN=1,FUN=unique) to find the unique values, but this leaves me with a list with arrays of different length: x <- apply(peaks,MARGIN=1,FUN=unique) [[1]] [1] 2 7 9 [[2]] [1] 10 6 8 [[3]] [1] 1 9 7 2 0 and using do.call("rbind",x) recycles the values of the shorter vectors instead of filling them with NA: do.call("rbind",x) [,1] [,2] [,3] [,4] [,5] [1,]27927 [2,] 1068 106 [3,]19720 So, I'd like to either take every element of the list and extend it with NAs to the length of the longest element, or rbind every element where missing places are filled with NAs instead of recycled values. Is this possible? Of course, the solution is trivial using a loop, but I'm trying to avoid this. Thanks for any suggestions. __ R-help@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@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
Combining the various approaches on the list, here's a simple one-liner that puts the NAs at the end: t(apply(mat,1,function(r) { dr<-duplicated(r); c( r[!dr], rep(NA,sum(dr)) ) )) If you don't care where the NAs are, the following is a tad shorter and perhaps clearer: mat[ t(apply(mat,1,duplicated)) ] < -NA # modifies mat -s __ R-help@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
(typos corrected) Combining the various approaches on the list, here's a simple one-liner that puts the NAs at the end: t(apply(mat,1,function(r) { dr<-duplicated(r); c( r[!dr], rep(NA,sum(dr)) ) })) If you don't care where the NAs are, the following is a tad shorter and perhaps clearer: mat[ t(apply(mat,1,duplicated)) ] <- NA # modifies mat -s On Fri, Feb 13, 2009 at 12:49 PM, Stavros Macrakis wrote: > Combining the various approaches on the list, here's a simple > one-liner that puts the NAs at the end: > > t(apply(mat,1,function(r) { dr<-duplicated(r); c( r[!dr], > rep(NA,sum(dr)) ) )) > > If you don't care where the NAs are, the following is a tad shorter > and perhaps clearer: > > mat[ t(apply(mat,1,duplicated)) ] < -NA # modifies mat > > -s > __ R-help@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.
Re: [R] Extending each element in a list, or rbind()-ing arrays of different length without recycling
That is very nice. Maybe just one slight improvement so to express it in a non-destructive form: replace(mat, t(apply(mat,1,duplicated)), NA) On Fri, Feb 13, 2009 at 12:58 PM, Stavros Macrakis wrote: > (typos corrected) > > Combining the various approaches on the list, here's a simple > one-liner that puts the NAs at the end: > >t(apply(mat,1,function(r) { dr<-duplicated(r); c( r[!dr], > rep(NA,sum(dr)) ) })) > > If you don't care where the NAs are, the following is a tad shorter > and perhaps clearer: > >mat[ t(apply(mat,1,duplicated)) ] <- NA # modifies mat > >-s > > On Fri, Feb 13, 2009 at 12:49 PM, Stavros Macrakis > wrote: >> Combining the various approaches on the list, here's a simple >> one-liner that puts the NAs at the end: >> >> t(apply(mat,1,function(r) { dr<-duplicated(r); c( r[!dr], >> rep(NA,sum(dr)) ) )) >> >> If you don't care where the NAs are, the following is a tad shorter >> and perhaps clearer: >> >> mat[ t(apply(mat,1,duplicated)) ] < -NA # modifies mat >> >> -s >> > > __ > R-help@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@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.