Asher Meir
2011-Dec-29 20:58 UTC
[R] Array element is function of its position in the array
I want to create a new array which selects values from an original array based on a function of the indices. That is: I want to create a new matrix Vnew[i,j,k]=Vold[i,j,ks] where ks is a function of the index elements i,j,k. I want to do this WITHOUT a loop. Call the function "ksfunction", and the array dimensions nis,njs,nks. I can do this using a loop as follows: # Loop version: Vnew<-array(NA,c(nis,njs,nks) for(i1 in 1:nis)for(j1 in 1:njs)for(k1 in 1:nks)Vnew[i1,j1,k1]<-Vold[i1,k1,ksfunction(i1,j1,k1)] I already know how to create an array of the ks's: ksarray[i,j,k]=ksfunction(i,j,k) # I have the array ksarray ready I don't want a loop because nis,njs, and nks are pretty large and it takes forever. Would appreciate help with this issue. [[alternative HTML version deleted]]
Greg Snow
2011-Dec-29 21:54 UTC
[R] Array element is function of its position in the array
Does "vnew <- vold[,,ks]" accomplish what you want? -- Gregory (Greg) L. Snow Ph.D. Statistical Data Center Intermountain Healthcare greg.snow at imail.org 801.408.8111> -----Original Message----- > From: r-help-bounces at r-project.org [mailto:r-help-bounces at r- > project.org] On Behalf Of Asher Meir > Sent: Thursday, December 29, 2011 1:58 PM > To: r-help at r-project.org > Subject: [R] Array element is function of its position in the array > > I want to create a new array which selects values from an original > array > based on a function of the indices. That is: > > I want to create a new matrix Vnew[i,j,k]=Vold[i,j,ks] where ks is a > function of the index elements i,j,k. I want to do this WITHOUT a loop. > > Call the function "ksfunction", and the array dimensions nis,njs,nks. I > can > do this using a loop as follows: > > # Loop version: > Vnew<-array(NA,c(nis,njs,nks) > for(i1 in 1:nis)for(j1 in 1:njs)for(k1 in > 1:nks)Vnew[i1,j1,k1]<-Vold[i1,k1,ksfunction(i1,j1,k1)] > > I already know how to create an array of the ks's: > ksarray[i,j,k]=ksfunction(i,j,k) # I have the array ksarray ready > > I don't want a loop because nis,njs, and nks are pretty large and it > takes > forever. > > Would appreciate help with this issue. > > [[alternative HTML version deleted]] > > ______________________________________________ > 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.
Jean V Adams
2011-Dec-29 22:32 UTC
[R] Array element is function of its position in the array
Asher Meir wrote on 12/29/2011 02:58:00 PM:> I want to create a new array which selects values from an original array > based on a function of the indices. That is: > > I want to create a new matrix Vnew[i,j,k]=Vold[i,j,ks] where ks is a > function of the index elements i,j,k. I want to do this WITHOUT a loop. > > Call the function "ksfunction", and the array dimensions nis,njs,nks. Ican> do this using a loop as follows: > > # Loop version: > Vnew<-array(NA,c(nis,njs,nks) > for(i1 in 1:nis)for(j1 in 1:njs)for(k1 in > 1:nks)Vnew[i1,j1,k1]<-Vold[i1,k1,ksfunction(i1,j1,k1)] > > I already know how to create an array of the ks's: > ksarray[i,j,k]=ksfunction(i,j,k) # I have the array ksarray ready > > I don't want a loop because nis,njs, and nks are pretty large and ittakes> forever. > > Would appreciate help with this issue.There may be non-loopy ways to do this, but in order (for me, at least) to suggest something, it would help to know what ksfunction() does. Jean [[alternative HTML version deleted]]
Jean V Adams
2011-Dec-30 00:36 UTC
[R] Array element is function of its position in the array
Asher Meir <asher.meir@gmail.com> wrote on 12/29/2011 04:47:21 PM:> Hello Jean. > > Thank you for your prompt response. > > I have an economic model. I start out with a list of asset levels > 1:nks. For every asset level, a person has nis possible income > levels and njs possible expense levels, with probabilities pi and > pj. They are independent so the probability matrix is just pi%o%pj. > > For each income level, expense level and starting asset level I will > end up with a specific known utility level next time around. That is > Vold. I know what Vold[income,expense,new savings level] is. I need > a weighted average of these. But the new savings level is itself a > function of income, expense and my current saving level. > > So Vnew[current k] = weighted probability of Vold[each income level, > each expense level, new savings given that income and that expense] > > For simplicity we can say that the ks is i+k-j --income+savings-expenses.> > I don't insist on solving this using the technique I asked about, > but that was how I went about approaching the issue. I would welcome > an alternative algorithm as much as an R fix! > > Many thanks > AsherThanks. That was helpful. I created a simple function, ksfunction() to represent the example you gave. I included two additional arguments to deal with newly created k values that extend beyond the third dimension of your initial array. Then, I took advantage of the fact that you can extract elements from an array using a matrix of indices. Excerpt from ?"[", the help file on extract: "A third form of indexing is via a numeric matrix with the one column for each dimension: each row of the index matrix then selects a single element of the array, and the result is a vector. Negative indices are not allowed in the index matrix. NA and zero values are allowed: rows of an index matrix containing a zero are ignored, whereas rows containing an NA produce an NA in the result." In the code below you can see what I did using a very small example for the initial array, Vold. When I increased the size of the array to 100^3, the matrix indexing method was 40 times faster than the looping method (i.e., it completed in 1/40th the time). By the way, it's helpful to cc the R-help with all of your replies, so that the thread of discussion is maintained for everyone to see. Hope this helps. Jean ksfunction <- function(i, j, k, maxk, def=NA) { newk <- i - j + k newk <- ifelse(newk < 1 | newk > maxk, def, i - j + k) newk } nis <- 5 njs <- 2 nks <- 5 tot <- nis*njs*nks Vold <- array(seq(tot), c(nis, njs, nks)) old.index <- cbind(i=rep(1:nis, njs*nks), j=rep(rep(1:njs, rep(nis, njs)), nks), k=rep(1:nks, rep(njs*nks, nks))) new.index <- cbind(old.index[, 1:2], k = ksfunction(old.index[, 1], old.index[, 2], old.index[, 3], nks)) Vnew <- array(Vold[new.index], c(nis, njs, nks))> On Fri, Dec 30, 2011 at 12:32 AM, Jean V Adams <jvadams@usgs.gov> wrote: > > Asher Meir wrote on 12/29/2011 02:58:00 PM: > > > > I want to create a new array which selects values from an originalarray> > based on a function of the indices. That is: > > > > I want to create a new matrix Vnew[i,j,k]=Vold[i,j,ks] where ks is a > > function of the index elements i,j,k. I want to do this WITHOUT aloop.> > > > Call the function "ksfunction", and the array dimensions nis,njs,nks.I can> > do this using a loop as follows: > > > > # Loop version: > > Vnew<-array(NA,c(nis,njs,nks) > > for(i1 in 1:nis)for(j1 in 1:njs)for(k1 in > > 1:nks)Vnew[i1,j1,k1]<-Vold[i1,k1,ksfunction(i1,j1,k1)] > > > > I already know how to create an array of the ks's: > > ksarray[i,j,k]=ksfunction(i,j,k) # I have the array ksarray ready > > > > I don't want a loop because nis,njs, and nks are pretty large and ittakes> > forever. > > > > Would appreciate help with this issue. > > > There may be non-loopy ways to do this, but in order (for me, at > least) to suggest something, it would help to know what ksfunction()does.> > Jean[[alternative HTML version deleted]]
Seemingly Similar Threads
- [PATCH net-next 11/14] vsock: add multi-transports support
- [RFC PATCH 10/13] vsock: add multi-transports support
- Grandstream firmware update DMTF Payload Type
- Asterisk SIP calls failing - not a proxy? What of RTP codec transcoding?
- Running script with double-click