A couple days ago, Mark Leeds asked about a solution that would basically stagger two lists, a and b, to return a list in the form of a[1], b[1], a[2], b[2], a[3].... In particular, the summary of his question was in reference to lists defined by x <- 5 tempin <- seq(1,1411, by=30) a <- tempin b <- tempin + x I offered the following function everyOther <- function(tempin, x){ tempout <- array(data=NA, dim=length(tempin)*2) tempout[seq(1,length(tempin)*2, by=2)]<-tempin tempout[seq(2,length(tempin)*2, by=2)]<-tempin+x tempout } which did what it was supposed to, and Gavin Simpson offered a similar function. Peter Dalgaard, however, supplied a much more elegant solution: c(rbind(tempin,tempin+5)) or rep(tempin, each=2) + c(0,5) I thought I'd bring this up as a new topic because it's really no longer related to what Mark first asked, but is there a way, perhaps from the documentation, that a user would know that c() and lists in general behave as they do in these two lines? Or would we just need to dig into the code? I am reminded of quote by Byron Ellis: "Contrary to popular belief the speed of R's interpreter is rarely the limiting factor to R's speed. People treating R like C is typically the limiting factor. You have vector operations, USE THEM." Not exactly the point, but close. Thanks! Jeff Spies http://www.nd.edu/~jspies/ [[alternative HTML version deleted]]
Jeffrey Robert Spies <jspies at nd.edu> writes:> A couple days ago, Mark Leeds asked about a solution that would > basically stagger two lists, a and b, to return a list in the form of > a[1], b[1], a[2], b[2], a[3].... In particular, the summary of his > question was in reference to lists defined by > > x <- 5 > tempin <- seq(1,1411, by=30) > a <- tempin > b <- tempin + x > > I offered the following function > > everyOther <- function(tempin, x){ > tempout <- array(data=NA, dim=length(tempin)*2) > tempout[seq(1,length(tempin)*2, by=2)]<-tempin > tempout[seq(2,length(tempin)*2, by=2)]<-tempin+x > tempout > } > > which did what it was supposed to, and Gavin Simpson offered a > similar function. Peter Dalgaard, however, supplied a much more > elegant solution: > > c(rbind(tempin,tempin+5)) > > or > > rep(tempin, each=2) + c(0,5) > > I thought I'd bring this up as a new topic because it's really no > longer related to what Mark first asked, but is there a way, perhaps > from the documentation, that a user would know that c() and lists in > general behave as they do in these two lines? Or would we just need > to dig into the code?(What lists? I see only vectors. Lists in R is a different kind of object.) There are a few basic principles in play here, once you know them, the rest follows; I'm not sure exactly where they are documented, but I'd guess at Venables & Ripley's books (MASS, S Programming) at least, the "Blue Book" on S, and possibly others. The first suggestion requires that you know or now about the following - matrices are vectors with dim attibutes, stored column-major ? binding rows into matrices with rbind() - c() removes attributes The second one requires - rep function, and its each- vector recycling in arithmetic> I am reminded of quote by Byron Ellis: "Contrary to popular belief > the speed of R's interpreter is rarely the limiting factor to R's > speed. People treating R like C is typically the limiting factor. You > have vector operations, USE THEM." Not exactly the point, but close. > > Thanks! > > Jeff Spies > http://www.nd.edu/~jspies/ > > > [[alternative HTML version deleted]] > > ______________________________________________ > 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 > and provide commented, minimal, self-contained, reproducible code. >-- O__ ---- Peter Dalgaard ?ster Farimagsgade 5, Entr.B c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
Berton Gunter wrote:> - c() removes attributes > > ** Documented in c()'s Help file***REALLY*** ??? Where? The only use of the word ``attribute'' in the help file is in ``See Also: 'unlist' and 'as.vector' to produce attribute-free vectors.'' Unless you already knew the fact that when m is a matrix c(m) gives a vector strung out in column order, you'd be very unlikely to discern that fact from the help file for c(). The only hint is that the output is described as being a vector. This is not exactly spoon-feeding the user. (Especially in view of the fact that a matrix ***is*** a vector --- with a dim attribute. Or so you keep telling us.) The help file talks about catenation (which is the essential role of c()) and expounds at length about the type of the result. The user is going to think in terms of c(v1,v2,v3), usw, where v1, v2 and v3 are ``genuine'' vectors''; it would never occur to him or her to apply c() to a matrix. There is no way on God's green earth that even the most diligent of neophytes is going to work out that c() has the effect on matrices that it does. EVEN IF the poor neophyte is so sophisticated as to have absorbed the idea that a matrix is a vector with a dim attribute. Which is perhaps a neat trick in designing data structures but is not, to put it mildly, intuitive. All too often it is useful to RTFM only if you already know the answer to your question. cheers, Rolf Turner rolf at math.unb.ca
Please, these are NOT lists. They are vectors: the difference should be clear even from 'An Introduction to R'. What Peter's first solution does is to create a matrix and then read it out in the default column-major order. This is again all discussed in 'An Introduction to R'. Using c() in this way is often frowned on: as.vector() is clearer. On Tue, 14 Nov 2006, Jeffrey Robert Spies wrote:> A couple days ago, Mark Leeds asked about a solution that would > basically stagger two lists, a and b, to return a list in the form of > a[1], b[1], a[2], b[2], a[3].... In particular, the summary of his > question was in reference to lists defined by > > x <- 5 > tempin <- seq(1,1411, by=30) > a <- tempin > b <- tempin + x > > I offered the following function > > everyOther <- function(tempin, x){ > tempout <- array(data=NA, dim=length(tempin)*2) > tempout[seq(1,length(tempin)*2, by=2)]<-tempin > tempout[seq(2,length(tempin)*2, by=2)]<-tempin+x > tempout > } > > which did what it was supposed to, and Gavin Simpson offered a > similar function. Peter Dalgaard, however, supplied a much more > elegant solution: > > c(rbind(tempin,tempin+5)) > > or > > rep(tempin, each=2) + c(0,5) > > I thought I'd bring this up as a new topic because it's really no > longer related to what Mark first asked, but is there a way, perhaps > from the documentation, that a user would know that c() and lists in > general behave as they do in these two lines? Or would we just need > to dig into the code? > > I am reminded of quote by Byron Ellis: "Contrary to popular belief > the speed of R's interpreter is rarely the limiting factor to R's > speed. People treating R like C is typically the limiting factor. You > have vector operations, USE THEM." Not exactly the point, but close. > > Thanks! > > Jeff Spies > http://www.nd.edu/~jspies/ > > > [[alternative HTML version deleted]] > > ______________________________________________ > 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 > and provide commented, minimal, self-contained, reproducible code. >-- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595