applying cbind (or any function) across all components in a list

14 messages
Open this post in threaded view
|
Report Content as Inappropriate

applying cbind (or any function) across all components in a list

 #If I have two lists as follows a1<-  array(1:6, dim=c(2,3)) a2<-  array(7:12, dim=c(2,3)) l1<-  list(a1,a2) a3<-  array(1:4, dim=c(2,2)) a4<-  array(5:8, dim=c(2,2)) l2<-  list(a3,a4) #how can I create a new list with the mean across all arrays within the list, so all components are included?  As an example for [[1]]; cbind((l1[[1]][,1]+l2[[1]][,1])/2, (l1[[1]][,2]+l2[[1]][,1])/2, (l1[[1]][,2]+l2[[1]][,2])/2, (l1[[1]][,3]+l2[[1]][,2])/2)
Open this post in threaded view
|
Report Content as Inappropriate

Re: applying cbind (or any function) across all components in a list

 This post has NOT been accepted by the mailing list yet. It is not exactly clear what you are trying to do - the example you gave doesn't have an intuitive pattern.  Could you check your example?  Are you sure that that combination of column means is what you want?
Open this post in threaded view
|
Report Content as Inappropriate

Re: applying cbind (or any function) across all components in a list

 The combination of column means in cbind is what I am trying to do.  I just don't know how to do it for every component (2 in this case) of the list.  I've been able to work with R to apply a function across all components when there is just one list but I am having trouble working with multiple lists at the same time.
Open this post in threaded view
|
Report Content as Inappropriate

Re: applying cbind (or any function) across all components in a list

 The "do.call" function may be what you want, but it is not completely clear.  If that does not solve your problem then try giving us an example of what your list looks like (the dput function can help) and what you want your end result to look like. On Thu, May 24, 2012 at 5:38 AM, Hans Thompson <[hidden email]> wrote: > The combination of column means in cbind is what I am trying to do.  I just > don't know how to do it for every component (2 in this case) of the list. > I've been able to work with R to apply a function across all components when > there is just one list but I am having trouble working with multiple lists > at the same time. > > -- > View this message in context: http://r.789695.n4.nabble.com/applying-cbind-or-any-function-across-all-components-in-a-list-tp4631128p4631187.html> Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ > [hidden email] 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. -- Gregory (Greg) L. Snow Ph.D. [hidden email] ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-helpPLEASE do read the posting guide http://www.R-project.org/posting-guide.htmland provide commented, minimal, self-contained, reproducible code.
Open this post in threaded view
|
Report Content as Inappropriate

Re: applying cbind (or any function) across all components in a list

 I'm confused why I haven't made clear what I am asking for help with.   I have two different lists with two (or many) components, [[1]] and [[2]].  One of the list has components with dim=c(2,3) and the other has dim=c(2,2).  I want to create a new list with components dim=c(2,4) by binding together the averages of the columns using > cbind((l1[[1]][,1]+l2[[1]][,1])/2, (l1[[1]][,2]+l2[[1]][,1])/2, (l1[[1]][,2]+l2[[1]][,2])/2, (l1[[1]][,3]+l2[[1]][,2])/2) which should put out:      [,1] [,2] [,3] [,4] [1,]    1    2    3    4 [2,]    2    3    4    5 my problem is finding out how I can apply this function to all the components within the list in the same function.
Open this post in threaded view
|
Report Content as Inappropriate

Re: applying cbind (or any function) across all components in a list

 In reply to this post by glsnow You don't make it clear if you want the two lists processed in parallel, but if so, this may be a step toward the function you want: Combine <- function(l1, l2) {   pattern <- cbind(c(1, 2, 2, 3), c(1, 1, 2, 2))   for (i in 1:length(l1)) {     print((l1[[i]][,pattern[,1]]+l2[[i]][,pattern[,2]])/2)   } } Combine(l1, l2) This simply prints the results, but you didn't indicate how you wanted the output organized. ---------------------------------------------- David L Carlson Associate Professor of Anthropology Texas A&M University College Station, TX 77843-4352 > -----Original Message----- > From: [hidden email] [mailto:r-help-bounces@r- > project.org] On Behalf Of Greg Snow > Sent: Thursday, May 24, 2012 10:17 AM > To: Hans Thompson > Cc: [hidden email] > Subject: Re: [R] applying cbind (or any function) across all components > in a list > > The "do.call" function may be what you want, but it is not completely > clear.  If that does not solve your problem then try giving us an > example of what your list looks like (the dput function can help) and > what you want your end result to look like. > > On Thu, May 24, 2012 at 5:38 AM, Hans Thompson > <[hidden email]> wrote: > > The combination of column means in cbind is what I am trying to do. >  I just > > don't know how to do it for every component (2 in this case) of the > list. > > I've been able to work with R to apply a function across all > components when > > there is just one list but I am having trouble working with multiple > lists > > at the same time. > > > > -- > > View this message in context: http://r.789695.n4.nabble.com/applying-> cbind-or-any-function-across-all-components-in-a-list- > tp4631128p4631187.html > > Sent from the R help mailing list archive at Nabble.com. > > > > ______________________________________________ > > [hidden email] 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. > > > > -- > Gregory (Greg) L. Snow Ph.D. > [hidden email] > > ______________________________________________ > [hidden email] 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. ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-helpPLEASE do read the posting guide http://www.R-project.org/posting-guide.htmland provide commented, minimal, self-contained, reproducible code.
Open this post in threaded view
|
Report Content as Inappropriate

Re: applying cbind (or any function) across all components in a list

 In reply to this post by Hans Thompson On May 24, 2012, at 12:49 PM, Hans Thompson wrote: > I'm confused why I haven't made clear what I am asking for help with. > > I have two different lists with two (or many) components, [[1]] and   > [[2]]. > One of the list has components with dim=c(2,3) and the other has   > dim=c(2,2). > I want to create a new list with components dim=c(2,4) by binding   > together > the averages of the columns using > >> cbind((l1[[1]][,1]+l2[[1]][,1])/2, (l1[[1]][,2]+l2[[1]][,1])/2, >> (l1[[1]][,2]+l2[[1]][,2])/2, (l1[[1]][,3]+l2[[1]][,2])/2 ) > > which should put out: > >     [,1] [,2] [,3] [,4] > [1,]    1    2    3    4 > [2,]    2    3    4    5 > > my problem is finding out how I can apply this function to all the > components within the list in the same function. Well, it's not clear what "function" you want applied to "what". In   fact, it's even less clear in this posting than it was in your first   one (since you assume, incorrectly, that we are looking at this on   Nabble. Readers of this list expect you to include context.)  I could   not figure out in your first posting how we should be considering the   fourth expression    {(l1[[1]][,3]+l2[[1]][,2])/2 } ... to be an "average" of anything since its indices do not match?   Perhaps equivalently, why should a 2 x 3 structure merged to   a 2 x 2 structure yield a 2 x 4 structure? -- David Winsemius, MD West Hartford, CT ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-helpPLEASE do read the posting guide http://www.R-project.org/posting-guide.htmland provide commented, minimal, self-contained, reproducible code.
Open this post in threaded view
|
Report Content as Inappropriate

Re: applying cbind (or any function) across all components in a list

 In reply to this post by David Carlson Yes. This gives me:      [,1] [,2] [,3] [,4] [1,]    1    2    3    4 [2,]    2    3    4    5      [,1] [,2] [,3] [,4] [1,]    6    7    8    9 [2,]    7    8    9   10 BUT, how can I have it still within components like [[1]]      [,1] [,2] [,3] [,4] [1,]    1    2    3    4 [2,]    2    3    4    5 [[2]]      [,1] [,2] [,3] [,4] [1,]    6    7    8    9 [2,]    7    8    9   10 How should I have phrased my question to be specific to this result? Thanks.
Open this post in threaded view
|
Report Content as Inappropriate

Re: applying cbind (or any function) across all components in a list

 In reply to this post by David Winsemius The function I am giving for context is cbind.  Are you asking how I would like to apply the answer to my question? I am trying to take the results of a Fluidigm SNP microarray, organized by assay into a list (each component is the results of one assay), find coordinate midpoints ([1,] and [2,] of my XX, XY, and YY clusters (these are genotypes) and is represented by l1.  l2 is the midpoint between XX/XY and XY/YY although I did not give this in my example for simplicity, and I am now trying to find the midpoint between these new midpoints and their closest genotype clusters. This is represented as cbind((l1[[1]][,1]+l2[[1]][,1])/2, (l1[[1]][,2]+l2[[1]][,1])/2, (l1[[1]][,2]+l2[[1]][,2])/2, (l1[[1]][,3]+l2[[1]][,2])/2) but only works for one assay in the list of 96.  I want to apply this to the entire list.  My entire code so far is: ## OPEN .CSV and ORGANIZE BY ASSAY file=""     {     rawdata <- read.csv(file, skip = 15)     OrgAssay <- split(rawdata, rawdata\$Assay)     ## RETURN MIDPOINTS FOR EACH CLUSTER WITHOUT NO CALLS     #for loop     ClustMidPts <-list()     for(locus in 1:length(names(OrgAssay))){     ClustMidPts[[locus]]<-t(cbind(tapply(OrgAssay[[locus]][,"Allele.X.1"], OrgAssay[[locus]][,"Final"], mean,na.rm=T),                                tapply(OrgAssay[[locus]][,"Allele.Y.1"], OrgAssay[[locus]][,"Final"], mean,na.rm=T)))}     names(ClustMidPts)=names(OrgAssay) ## CREATE CLUSTER-CLUSTER MIDPOINT     #for loop     ClustClustMidPts <- list()     for(locus in 1:length(names(ClustMidPts))){     ClustClustMidPts[[locus]] <- cbind(XXYX=(ClustMidPts[[locus]][,"XX"]+ClustMidPts[[locus]][,"YX"])/2, YXYY=(ClustMidPts[[locus]][,"YX"]+ClustMidPts[[locus]][,"YY"])/2) }     names(ClustClustMidPts)=names(ClustMidPts) Please also let me know how I messed up the formatting because it shows up fine in gmail even when I post on Nabble.  How did I assume you were using Nabble?  Is this topic included in the posting guide?
Open this post in threaded view
|
Report Content as Inappropriate

Re: applying cbind (or any function) across all components in a list

Open this post in threaded view
|
Report Content as Inappropriate

Re: applying cbind (or any function) across all components in a list

 In reply to this post by Hans Thompson This should give you what you want and it is simpler than the earlier version: a1<-  array(1:6, dim=c(2,3)) a2<-  array(7:12, dim=c(2,3)) l1<-  list(a1,a2) a3<-  array(1:4, dim=c(2,2)) a4<-  array(5:8, dim=c(2,2)) l2<-  list(a3,a4) pattern <- cbind(c(1, 2, 2, 3), c(1, 1, 2, 2)) lnew <- lapply(1:length(l1), function(i)   (l1[[i]][,pattern[,1]]+l2[[i]][,pattern[,2]])/2) lnew If all the information from your several posts had been included in the original request, we could have responded more quickly. ---------------------------------------------- David L Carlson Associate Professor of Anthropology Texas A&M University College Station, TX 77843-4352 > -----Original Message----- > From: [hidden email] [mailto:r-help-bounces@r- > project.org] On Behalf Of Hans Thompson > Sent: Thursday, May 24, 2012 5:19 PM > To: [hidden email] > Subject: Re: [R] applying cbind (or any function) across all components > in a list > > Yes. This gives me: > >      [,1] [,2] [,3] [,4] > [1,]    1    2    3    4 > [2,]    2    3    4    5 >      [,1] [,2] [,3] [,4] > [1,]    6    7    8    9 > [2,]    7    8    9   10 > > BUT, how can I have it still within components like > > [[1]] >      [,1] [,2] [,3] [,4] > [1,]    1    2    3    4 > [2,]    2    3    4    5 > > [[2]] >      [,1] [,2] [,3] [,4] > [1,]    6    7    8    9 > [2,]    7    8    9   10 > > How should I have phrased my question to be specific to this result? > > Thanks. > > -- > View this message in context: http://r.789695.n4.nabble.com/applying-> cbind-or-any-function-across-all-components-in-a-list- > tp4631128p4631258.html > Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ > [hidden email] 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. ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-helpPLEASE do read the posting guide http://www.R-project.org/posting-guide.htmland provide commented, minimal, self-contained, reproducible code.
Open this post in threaded view
|
Report Content as Inappropriate

Re: applying cbind (or any function) across all components in a list

 In reply to this post by Hans Thompson Hello, Let me give it a try. This last post made it clear, I hope. I have two interpretations of your problem. 1. 'l1' only has three columns, corresponding to clusters (genotypes) XX, XY and YY, and 'l2' has one less column, corresponding to the midpoints between their closest genotype cluster. 2. 'l1' can have any number of columns and 'l2' is the same as above, i.e., has one less column. In any case, the result is not the pairwise products of all possible combinations of columns of 'l1' and 'l2' matrices, but only those at a certain distance. In this case, fun2 below is more general. fun1 <- function(x, y){      cbind((x[, 1] + y[, 1])/2, (x[, 2] + y[, 1])/2,          (x[, 2] + y[, 2])/2, (x[, 3] + y[, 2])/2) } fun2 <- function(x, y){      midpoint <- function(i, j) (x[, i] + y[, j])/2      colx <- ncol(x)      res <- matrix(nrow = nrow(x), ncol = 2*colx - 2)      k <- 1      res[, k] <- midpoint(1, 1)      for(cx in seq_len(colx)[-c(1, colx)])          for(dist in 1:0)              res[, k <- k + 1] <- midpoint(cx, cx - dist)      res[, k + 1] <- midpoint(colx, colx - 1)      res } lapply(seq_len(length(l1)), function(i) fun1(l1[[i]], l2[[i]])) lapply(seq_len(length(l1)), function(i) fun2(l1[[i]], l2[[i]])) If I'm wrong, sorry for the mess. Rui Barradas Em 25-05-2012 11:00, [hidden email] escreveu: > Date: Thu, 24 May 2012 15:37:51 -0700 (PDT) > From: Hans Thompson<[hidden email]> > To:[hidden email] > Subject: Re: [R] applying cbind (or any function) across all > components in a list > Message-ID:<[hidden email]> > Content-Type: text/plain; charset=us-ascii > > The function I am giving for context is cbind.  Are you asking how I would > like to apply the answer to my question? > > I am trying to take the results of a Fluidigm SNP microarray, organized by > assay into a list (each component is the results of one assay), find > coordinate midpoints ([1,] and [2,] of my XX, XY, and YY clusters (these are > genotypes) and is represented by l1.  l2 is the midpoint between XX/XY and > XY/YY although I did not give this in my example for simplicity, and I am > now trying to find the midpoint between these new midpoints and their > closest genotype clusters. This is represented as > > cbind((l1[[1]][,1]+l2[[1]][,1])/2, (l1[[1]][,2]+l2[[1]][,1])/2, > (l1[[1]][,2]+l2[[1]][,2])/2, (l1[[1]][,3]+l2[[1]][,2])/2) > > but only works for one assay in the list of 96.  I want to apply this to the > entire list.  My entire code so far is: > > ## OPEN .CSV and ORGANIZE BY ASSAY > > > file="" >      { >      rawdata<- read.csv(file, skip = 15) >      OrgAssay<- split(rawdata, rawdata\$Assay) > > >      ## RETURN MIDPOINTS FOR EACH CLUSTER WITHOUT NO CALLS > >      #for loop >      ClustMidPts<-list() > >      for(locus in 1:length(names(OrgAssay))){ >      ClustMidPts[[locus]]<-t(cbind(tapply(OrgAssay[[locus]][,"Allele.X.1"], > OrgAssay[[locus]][,"Final"], mean,na.rm=T), >                                 tapply(OrgAssay[[locus]][,"Allele.Y.1"], > OrgAssay[[locus]][,"Final"], mean,na.rm=T)))} > >      names(ClustMidPts)=names(OrgAssay) > > > ## CREATE CLUSTER-CLUSTER MIDPOINT > >      #for loop >      ClustClustMidPts<- list() > >      for(locus in 1:length(names(ClustMidPts))){ >      ClustClustMidPts[[locus]]<- > cbind(XXYX=(ClustMidPts[[locus]][,"XX"]+ClustMidPts[[locus]][,"YX"])/2, > YXYY=(ClustMidPts[[locus]][,"YX"]+ClustMidPts[[locus]][,"YY"])/2) > } > >      names(ClustClustMidPts)=names(ClustMidPts) > > > Please also let me know how I messed up the formatting because it shows up > fine in gmail even when I post on Nabble.  How did I assume you were using > Nabble?  Is this topic included in the posting guide? > > -- > View this message in context:http://r.789695.n4.nabble.com/applying-cbind-or-any-function-across-all-components-in-a-list-tp4631128p4631260.html> Sent from the R help mailing list archive at Nabble.com. > > ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-helpPLEASE do read the posting guide http://www.R-project.org/posting-guide.htmland provide commented, minimal, self-contained, reproducible code.
Open this post in threaded view
|
Report Content as Inappropriate

Re: applying cbind (or any function) across all components in a list

 Thank you everyone for working through the confusion from me posting from Nabble and missing context. Both Rui's and David's solutions are working for my problem.  Rui's first interpretation is the application I was looking for but I was also more generally interested in how to do the second one if I wanted. I still don't understand how I would use function(i) for working with components of lists in the future though.  Is there a simpler example?  I'm going to play with using seq_len also. On Fri, May 25, 2012 at 8:20 AM, Rui Barradas <[hidden email]> wrote: > Hello, > > Let me give it a try. > This last post made it clear, I hope. I have two interpretations of your > problem. > > 1. 'l1' only has three columns, corresponding to clusters (genotypes) XX, > XY and YY, and 'l2' has one less column, corresponding to the midpoints > between their closest genotype cluster. > > 2. 'l1' can have any number of columns and 'l2' is the same as above, > i.e., has one less column. > > In any case, the result is not the pairwise products of all possible > combinations of columns of 'l1' and 'l2' matrices, but only those at a > certain distance. In this case, fun2 below is more general. > > fun1 <- function(x, y){ >    cbind((x[, 1] + y[, 1])/2, (x[, 2] + y[, 1])/2, >        (x[, 2] + y[, 2])/2, (x[, 3] + y[, 2])/2) > } > > > fun2 <- function(x, y){ >    midpoint <- function(i, j) (x[, i] + y[, j])/2 > >    colx <- ncol(x) >    res <- matrix(nrow = nrow(x), ncol = 2*colx - 2) >    k <- 1 >    res[, k] <- midpoint(1, 1) >    for(cx in seq_len(colx)[-c(1, colx)]) >        for(dist in 1:0) >            res[, k <- k + 1] <- midpoint(cx, cx - dist) >    res[, k + 1] <- midpoint(colx, colx - 1) >    res > } > > lapply(seq_len(length(l1)), function(i) fun1(l1[[i]], l2[[i]])) > lapply(seq_len(length(l1)), function(i) fun2(l1[[i]], l2[[i]])) > > > If I'm wrong, sorry for the mess. > > Rui Barradas > > > Em 25-05-2012 11:00, [hidden email] escreveu: > >> Date: Thu, 24 May 2012 15:37:51 -0700 (PDT) >> From: Hans Thompson >> > >> >> To:[hidden email] >> Subject: Re: [R] applying cbind (or any function) across all >>        components in a list >> Message-ID:<1337899071674-**[hidden email]<[hidden email]> >> > >> Content-Type: text/plain; charset=us-ascii >> >> >> The function I am giving for context is cbind.  Are you asking how I would >> like to apply the answer to my question? >> >> I am trying to take the results of a Fluidigm SNP microarray, organized by >> assay into a list (each component is the results of one assay), find >> coordinate midpoints ([1,] and [2,] of my XX, XY, and YY clusters (these >> are >> genotypes) and is represented by l1.  l2 is the midpoint between XX/XY and >> XY/YY although I did not give this in my example for simplicity, and I am >> now trying to find the midpoint between these new midpoints and their >> closest genotype clusters. This is represented as >> >> cbind((l1[[1]][,1]+l2[[1]][,1]**)/2, (l1[[1]][,2]+l2[[1]][,1])/2, >> >> (l1[[1]][,2]+l2[[1]][,2])/2, (l1[[1]][,3]+l2[[1]][,2])/2) >> >> but only works for one assay in the list of 96.  I want to apply this to >> the >> >> entire list.  My entire code so far is: >> >> ## OPEN .CSV and ORGANIZE BY ASSAY >> >> >> file="" >>     { >>     rawdata<- read.csv(file, skip = 15) >>     OrgAssay<- split(rawdata, rawdata\$Assay) >> >> >>     ## RETURN MIDPOINTS FOR EACH CLUSTER WITHOUT NO CALLS >> >>     #for loop >>     ClustMidPts<-list() >> >>     for(locus in 1:length(names(OrgAssay))){ >>     ClustMidPts[[locus]]<-t(cbind(**tapply(OrgAssay[[locus]][,"** >> Allele.X.1"], >> OrgAssay[[locus]][,"Final"], mean,na.rm=T), >>                                tapply(OrgAssay[[locus]][,"**Allele.Y.1"], >> OrgAssay[[locus]][,"Final"], mean,na.rm=T)))} >> >>     names(ClustMidPts)=names(**OrgAssay) >> >> >> ## CREATE CLUSTER-CLUSTER MIDPOINT >> >>     #for loop >>     ClustClustMidPts<- list() >> >>     for(locus in 1:length(names(ClustMidPts))){ >>     ClustClustMidPts[[locus]]<- >> cbind(XXYX=(ClustMidPts[[**locus]][,"XX"]+ClustMidPts[[** >> locus]][,"YX"])/2, >> YXYY=(ClustMidPts[[locus]][,"**YX"]+ClustMidPts[[locus]][,"**YY"])/2) >> } >> >>     names(ClustClustMidPts)=names(**ClustMidPts) >> >> >> Please also let me know how I messed up the formatting because it shows up >> fine in gmail even when I post on Nabble.  How did I assume you were using >> Nabble?  Is this topic included in the posting guide? >> >> -- >> View this message in context:http://r.789695.n4.**>> nabble.com/applying-cbind-or-**any-function-across-all-** >> components-in-a-list-**tp4631128p4631260.html >> >> Sent from the R help mailing list archive at Nabble.com. >> >> >>         [[alternative HTML version deleted]] ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-helpPLEASE do read the posting guide http://www.R-project.org/posting-guide.htmland provide commented, minimal, self-contained, reproducible code.