Dear all, I am trying to learn lapply. I would like, as a test case, to try the lapply alternative for the Shadowlist<-array(data=NA,dim=c(dimx,dimy,dimmaps)) for (i in c(1:dimx)){ Shadowlist[,,i]<-i } ---so I wrote the following--- returni <-function(i,ShadowMatrix) {ShadowMatrix<-i} lapply(seq(1:dimx),Shadowlist[,,seq(1:dimx)],returni) So far I do not get same results with both ways. Could you please help me understand what might be wrong? Regards Alex
Hi Alaios, there are some problems with your code: 1. In the expression "Shadowlist[,,i]<-i", i corresponds to dimmaps, not dimx. The for loop should be either for (i in c(1:dimmaps)){ Shadowlist[,,i]<-i } or for (i in c(1:dimx)){ Shadowlist[i,,]<-i } 2. in lapply, the function must be second argument, your expression lapply(seq(1:dimx),Shadowlist[,,seq(1:dimx)],returni) fails because lapply wants to call Shadowlist[...] as a function. You probably meant (including the correction above): lapply(seq(1:dimmaps),returni,Shadowlist[,,seq(1:dimmaps)]) or lapply(seq(1:dimx),returni,Shadowlist[seq(1:dimx),,]) 3. lapply always returns a list, there is no way to make it return an array. apply is better to deal with arrays, but as far as I know it cannot return arrays with dimension greater than 2. Finally a general remark for future posts: Please make sure your examples are self-contained and executable (i.e. they don't throw an error and they do not depend on undefined variables, such as dimx etc. in this case) Best regards, Andreas -- Andreas Borg Medizinische Informatik UNIVERSIT?TSMEDIZIN der Johannes Gutenberg-Universit?t Institut f?r Medizinische Biometrie, Epidemiologie und Informatik Obere Zahlbacher Stra?e 69, 55131 Mainz www.imbei.uni-mainz.de Telefon +49 (0) 6131 175062 E-Mail: borg at imbei.uni-mainz.de Diese E-Mail enth?lt vertrauliche und/oder rechtlich gesch?tzte Informationen. Wenn Sie nicht der richtige Adressat sind oder diese E-Mail irrt?mlich erhalten haben, informieren Sie bitte sofort den Absender und l?schen Sie diese Mail. Das unerlaubte Kopieren sowie die unbefugte Weitergabe dieser Mail und der darin enthaltenen Informationen ist nicht gestattet.
Hello Alex. A few issues: * you want seq(dimx) instead of seq(1:dimx) (d'oh) * I think you have problems with your dimensions in the original code as well: you use i, which runs up to dimx as an indexer for your third dimension, of size dimmaps. If dimx > dimmaps, you're in for unexpected results. * basic idea of the apply-style functions (nicked *apply below): - first argument = a collection of items to run over. Could be a list or a vector - second argument a function, that could take any of the items in the collection as its first argument - other arguments: either tuning parameters (like simplify) for *apply or passed on as more arguments to the function - each item from the collection is sequentially fed as the first argument, the extra arguments (always the same) are also passed to *apply. - normally, the results of each call are collected into a list, where the names of the list items refers to your original collection. In more elaborate versions (sapply) and under some circumstances, this list is transformed into a simpler structure. * your test case is rather complicated: I don't think there is a way to make lapply or one of its cousins to return a threedimensional array just like that. With sapply (and simplify=TRUE, the default), if the result for each item of your collection has the same length, the result is coerced into a twodimensional array with one column for each item in your collection. * on the other hand, for your example, you probably don't want to use *apply functions nor loops: it can be done with some clever use of seq and rep and dim, for sure. All in all, it seems you may need to get your basics up to speed first, then shift to *apply (and use a simpler example to get started, like: given a matrix with two columns, create a vector holding the differences and the sums of the columns - I know this can be done without *apply as well, but apart from that it is a more attainable exercise). Good luck to you on that! HTH, Nick Sabbe -- ping: nick.sabbe at ugent.be link: http://biomath.ugent.be wink: A1.056, Coupure Links 653, 9000 Gent ring: 09/264.59.36 -- Do Not Disapprove -----Original Message----- From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of Alaios Sent: woensdag 30 maart 2011 8:31 To: R-help at r-project.org Subject: [R] a for loop to lapply Dear all, I am trying to learn lapply. I would like, as a test case, to try the lapply alternative for the Shadowlist<-array(data=NA,dim=c(dimx,dimy,dimmaps)) for (i in c(1:dimx)){ Shadowlist[,,i]<-i } ---so I wrote the following--- returni <-function(i,ShadowMatrix) {ShadowMatrix<-i} lapply(seq(1:dimx),Shadowlist[,,seq(1:dimx)],returni) So far I do not get same results with both ways. Could you please help me understand what might be wrong? Regards Alex ______________________________________________ R-help at 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.
Hi Alex, lapply is not a substitute for for, so it not only does things differenly, it does a different thing.> Shadowlist<-array(data=NA,dim=c(dimx,dimy,dimmaps)) > for (i in c(1:dimx)){ > ? ?Shadowlist[,,i]<-i > }Note that your test case is not reproducible as you haven't defined dimx, dimy, dimmaps.> returni <-function(i,ShadowMatrix) {ShadowMatrix<-i} > lapply(seq(1:dimx),Shadowlist[,,seq(1:dimx)],returni) > So far I do not get same results with both ways. > Could you please help me understand what might be wrong?I don't suppose you're getting any results with lapply this way at all. 1. The second argument to lapply should be a function but here you have something else. 2. Lapply returns a list of results and does *not* modify its arguments. If you really want to, you can use <<- within lapply, so your example (slightly modified) could look something like this: A<-B<- array(data=NA,dim=c(5,5,5)) for (i in c(1:5))A[,,i]<-i lapply(1:5, function(i) B[,,i][]<<-i) all.equal(A,B) Notice that in this case, what lapply returns is not identical to what it does to B, and this is not nice. The normal use of lapply is applying a function to each element of a list (or a vector)... C<- lapply(1:5, diag) # a list with 5 elements, matrices with increasing size lapply(C, dim) # dimensions of each matrix # sapply would give it in a more convenient form # or you could print it more concisely as str(lapply(C, dim)) the equivalent with for would be: for(i in 1:5) print(dim(C[[i]])) The _for_ version is less short and there are much more ['s and ('s to take care about so lapply/sapply is easier here. Notice also that it creates a new variable (i) or potentially overwrites anything named i in your workspace. Lapply doesn't do it unless you explicitly tell it to (using things like <<- , not recommended). Good luck, Kenn
alaios wrote:> > I am trying to learn lapply. > I would like, as a test case, to try the lapply alternative for the > Shadowlist<-array(data=NA,dim=c(dimx,dimy,dimmaps)) > for (i in c(1:dimx)){ > Shadowlist[,,i]<-i > } > ---so I wrote the following--- > returni <-function(i,ShadowMatrix) {ShadowMatrix<-i} > lapply(seq(1:dimx),Shadowlist[,,seq(1:dimx)],returni) > >The basic problem is that you have an array, but you name it "list". This is valid code, but by calling it so you shot a list-bullet into your vector-foot. An array should be treated like an array, and the best way to fill it uses simple vectoring. No loop, no xapply needed. Use lapply if you have a data.frame or (more generic) a real list, which can contain rather heterogeneous components. And try to forget what you learned in your c++ course: Seeing lapply(,Shadowlist[,,seq(1:dimx)],) to fill Shadowlist tell me that it must be wrong, because R (in all recommended cases) never "fills" a parameter passed to it like c(++) can do. You should always have something like: Shadowlist <- lapply(....) Dieter #------ dimx=2 # don't forget to make the example self-contained dimy=3 dimmaps=3 ShadowArray<-array(data=NA,dim=c(dimx,dimy,dimmaps)) # Are you shure you mean "dimx" ? But let's assume it is correct for (i in c(1:dimx)){ ShadowArray[,,i]<-i } ShadowArray ShadowArray<-array(data=NA,dim=c(dimx,dimy,dimmaps)) ShadowArray[,,1:dimx]<-1:dimx ShadowArray -- View this message in context: http://r.789695.n4.nabble.com/a-for-loop-to-lapply-tp3417169p3417377.html Sent from the R help mailing list archive at Nabble.com.