As currently implemented it works for both "Location" and "Destination" (I really should think of some better variable names) of any dimensionality, but it does assume that if say, you give a 2d location, those correspond to the first two dimensions of destination.
But if you give 1d or 3d, e.g., for a 5d destination, it can fill out as appropriate. If you want to say give it the 2nd and 3rd dimensions, I'd suggest you put an optional argument and command using the aperm() function immediately after Location = array(Location,dim(Destination)). e.g., cubeValue <- function(Insert, Destination, Location, permutation = NULL) { .... if (!is.null(permutation)) {Location = aperm(Location, permutation)} .... } You might need to play with aperm to get a sense of how it "thinks" but that should do it. Alternatively, you can put in something like theseDims = c(2,3) and then write a line or two that figures out the appropriate permutation from there. In 3D, it's not hard but I'm not sure if there's a single obvious way to generalize to higher dimensions: if I have some time to think about it I'll get back to you. # for 3D permutation = c(theseDims, setdiff(1:3,theseDims)) Michael Weylandt On Thu, Aug 4, 2011 at 5:54 PM, Jannis <bt_jan...@yahoo.de> wrote: > Your function only works for the first dimensions (e.g. indices indicating > the positions in the first two dimensions in datacube), correct? > > Otherwise it looks very handy! And certainly more elegent than my function > monster! > > Jannis > > > On 08/04/2011 09:58 PM, R. Michael Weylandt wrote: > >> Hi Jannis, >> >> Like Gene, I'm not entirely sure what your code is intended to do, but it >> wasn't hard to adapt mine to at least print out the desired slice through >> the higher-dimensional array: >> >> cubeValues<- function(Insert, Destination, Location) { >> Location = as.matrix(Location) >> Location = array(Location,dim(**Destination)) >> if (is.null(Insert)) { >> Destination = round(Destination,3) >> Destination[!Location] = NA >> print(Destination) >> return(invisible()) >> } >> Destination[Location]<- Insert >> return(Destination) >> } >> >> If Insert = NULL, it adopts a printing rather than value assigning >> behavior. >> >> >> If you could indicate how you want the values when they come out, it's >> pretty easy to adapt this to do whatever, but I can't just pull out >> subarrays of arbitrary shape while keeping shape: e.g., >> >> x = matrix(1:4,2,2,byrow=T) >> y = rbind(c(T,F),c(F,T)) >> >> is(x[y]) >>> >> "vector" >> >> If you just want the values in a vector, take this version of my code: >> >> cubeValues<- function(Insert, Destination, Location) { >> Location = as.matrix(Location) >> Location = array(Location,dim(**Destination)) >> if (is.null(Insert)) { >> return(Destination[Location]) >> } >> Destination[Location]<- Insert >> return(Destination) >> } >> >> It sounds like you've got what you want, but hopefully this will be of >> some >> use to anyone who stumbles across this and, like Gene& myself, doesn't >> really get your code. >> >> NB: I have not tested the provided code very much -- it relies on the >> array() function to repeat Location as appropriate. If you know how R >> repeats smaller arrays to make them fit big arrays, this should be fine >> for >> you -- caveat code-or. >> >> Michael Weylandt >> >> PS -- The combinations() function of the gtools package might be of help >> to >> you as well. We could get the entire example Gene got by >> >> ans = combinations(1:4,2,repeats.**allowed=T) >> rbind(cbind(ans,4),cbind(ans,**1)) >> >> and it's probably not hard to simplify the entire code as desired. >> >> On Thu, Aug 4, 2011 at 6:33 AM, Jannis<bt_jan...@yahoo.de> wrote: >> >> Thanks, Michael. I was, however, after a function I coul use for both >>> extracting and replacing subarrays. In case anybody else stumbles over >>> this >>> problem, here is my solution. Its programming is most probably horribly >>> clumsy: >>> >>> >>> ind.datacube = function( >>> ##title<< create logical index matrices for multidimensional datacubes >>> datacube ##<< array: datacube from which to extract the subparts >>> , logical.ind ##<< logical array: TRUE/FALSE index matrix for a subset >>> of >>> the dimensions >>> ## of datacube. The size of logical.ind`s dimesnions >>> has >>> to match the >>> ## sizes of the corresponding dimesnions in datacube. >>> , dims='auto' ##<< integer vector or 'auto' : indices of the >>> dimensions >>> in datacube corresponding >>> ## to the dimensions of logical.ind. If set to 'auto' >>> this matching is tried to >>> ## be accomplished by comparing the sizes of the >>> dimensions of the two objects. >>> ) >>> { >>> if (sum(logical.ind) == 0) { >>> stop('No TRUE value in index matrix!') >>> } else { >>> if (dims == 'auto') >>> { >>> if (is.null(dim(logical.ind)[1])) { >>> size.ind = length(logical.ind) >>> logical.ind = matrix(logical.ind,ncol=1) >>> } else { >>> size.ind = dim(logical.ind) >>> } >>> dims = match(size.ind, dim(datacube)) >>> if (sum(duplicated(size.ind))> 0 || sum(duplicated(dims))> 0 >>> ) >>> stop('dimensions do not match unambigously. Supply dims >>> manually!') >>> } >>> dims.nonapply<- setdiff(1:length(dim(datacube)****),dims) >>> ind.matrix<- which(logical.ind, arr.ind = TRUE) >>> >>> args.expand.grid<- list() >>> counter = 1 >>> for (i in 1: length(dim(datacube))) >>> { >>> if (is.element(i,dims.nonapply)) { >>> args.expand.grid[[i]] = 1:dim(datacube)[dims.nonapply[** >>> **i]] >>> } else { >>> args.expand.grid[[i]] = ind.matrix[,counter] >>> counter = counter + 1 >>> } >>> } >>> >>> ind.all<- as.matrix(do.call(expand.grid, args.expand.grid)) >>> ind.matrix<- ind.all[,order(c(dims.****nonapply,dims))] >>> >>> } >>> ##value<< integer index matrix which can be used to index datacube >>> ind.matrix >>> >>> } >>> >>> >>> On 08/04/2011 12:12 AM, R. Michael >>> Weylandt<michael.weylandt@**gmail.com<michael.weyla...@gmail.com> >>> > >>> wrote: >>> >>> This might be a little late: but how about this (slightly clumsy) >>>> >>>>> function: >>>>> >>>>> putValues<- function(Insert, Destination, Location) { >>>>> Location = as.matrix(Location) >>>>> Location = array(Location,dim(****Destination)) >>>>> Destination[Location]<- Insert >>>>> return(Destination) >>>>> } >>>>> >>>>> It currently assumes that the location array lines up in dimension >>>>> order, >>>>> but other than that seems to work pretty well. If you want, it >>>>> shouldn't >>>>> be >>>>> hard to change it to take in a set of dimensions to arrange Location >>>>> along. >>>>> If you like any of the other suggested behaviors, you could put in a >>>>> is.null(Insert) option that returns the desired subset of values. I >>>>> haven't >>>>> tested it completely, but for a few sample inputs, it seems be do as >>>>> desired. >>>>> >>>>> Michael >>>>> >>>>> >>>>> On Wed, Aug 3, 2011 at 5:00 PM, Jannis<bt_jan...@yahoo.de> wrote: >>>>> >>>>> Thanks for all the replies!Unfortunately the solutions only work for >>>>> >>>>>> extracting subsets of the data (which was exactly what I was asking >>>>>> for) >>>>>> and >>>>>> not to replace subsets with other values. I used them, however, to >>>>>> program a >>>>>> rather akward function to do that. Seems I found one of the few >>>>>> aspects >>>>>> where Matlab actually is slightly easier to use than R. >>>>>> >>>>>> >>>>>> Thanks for your help! >>>>>> Jannis >>>>>> >>>>>> On 08/01/2011 05:50 PM, Gene Leynes wrote: >>>>>> >>>>>> What do you think about this? >>>>>> >>>>>>> apply(data, 3, '[', indices) >>>>>>> >>>>>>> >>>>>>> On Mon, Aug 1, 2011 at 4:38 AM, Jannis<bt_jan...@yahoo.de> wrote: >>>>>>> >>>>>>> Dear R community, >>>>>>> >>>>>>> I have a general question regarding indexing in multidiemensional >>>>>>>> arrays. >>>>>>>> >>>>>>>> Imagine I have a three dimensional array and I only want to extract >>>>>>>> on >>>>>>>> vector along a single dimension from it: >>>>>>>> >>>>>>>> >>>>>>>> data<- array(rnorm(64),dim=c(4,4,4)) >>>>>>>> >>>>>>>> result<- data[1,1,] >>>>>>>> >>>>>>>> If I want to extract more than one of these vectors, it would now >>>>>>>> really >>>>>>>> help me to supply a logical matrix of the size of the first two >>>>>>>> dimensions: >>>>>>>> >>>>>>>> >>>>>>>> indices<- matrix(FALSE,ncol=4,nrow=4) >>>>>>>> indices[1,3]<- TRUE >>>>>>>> indices[4,1]<- TRUE >>>>>>>> >>>>>>>> result<- data[indices,] >>>>>>>> >>>>>>>> This, however would give me an error. I am used to this kind of >>>>>>>> indexing >>>>>>>> from Matlab and was wonderingt whether there exists an easy way to >>>>>>>> do >>>>>>>> this >>>>>>>> in R without supplying complicated index matrices of all three >>>>>>>> dimensions or >>>>>>>> logical vectors of the size of the whole matrix? >>>>>>>> >>>>>>>> The only way I could imagine would be to: >>>>>>>> >>>>>>>> result<- data[rep(as.vector(indices),********times=4)] >>>>>>>> >>>>>>>> but this seems rather complicated and also depends on the order of >>>>>>>> the >>>>>>>> dimensions I want to extract. >>>>>>>> >>>>>>>> >>>>>>>> I do not want R to copy Matlabs behaviour, I am just wondering >>>>>>>> whether >>>>>>>> I >>>>>>>> missed one concept of indexing in R? >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> Thanks a lot >>>>>>>> Jannis >>>>>>>> >>>>>>>> ______________________________********________________ >>>>>>>> R-help@r-project.org mailing list >>>>>>>> https://stat.ethz.ch/mailman/********listinfo/r-help<https://stat.ethz.ch/mailman/******listinfo/r-help> >>>>>>>> <https://**stat.ethz.ch/mailman/******listinfo/r-help<https://stat.ethz.ch/mailman/****listinfo/r-help> >>>>>>>> > >>>>>>>> <https://**stat.ethz.ch/**mailman/****listinfo/r-help<http://stat.ethz.ch/mailman/****listinfo/r-help> >>>>>>>> <ht**tps://stat.ethz.ch/mailman/****listinfo/r-help<https://stat.ethz.ch/mailman/**listinfo/r-help> >>>>>>>> > >>>>>>>> >>>>>>>> <https://stat.**ethz.ch/****mailman/listinfo/r-**help<http://ethz.ch/**mailman/listinfo/r-**help> >>>>>>>> <http**://ethz.ch/mailman/listinfo/r-****help<http://ethz.ch/mailman/listinfo/r-**help> >>>>>>>> > >>>>>>>> <http**s://stat.ethz.ch/**mailman/**listinfo/r-help<http://stat.ethz.ch/mailman/**listinfo/r-help> >>>>>>>> <http**s://stat.ethz.ch/mailman/**listinfo/r-help<https://stat.ethz.ch/mailman/listinfo/r-help> >>>>>>>> > >>>>>>>> >>>>>>>> PLEASE do read the posting guide http://www.R-project.org/** >>>>>>>> posting-guide.html<http://www.******R-project.org/posting-** >>>>>>>> guide.** >>>>>>>> **html<http://www.R-project.****org/posting-guide.html<http://** >>>>>>>> www.R-project.org/posting-**guide.html<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<https://stat.ethz.ch/mailman/****listinfo/r-help> >>>>>> <https://**stat.ethz.ch/mailman/****listinfo/r-help<https://stat.ethz.ch/mailman/**listinfo/r-help> >>>>>> > >>>>>> <https://stat.**ethz.ch/**mailman/listinfo/r-**help<http://ethz.ch/mailman/listinfo/r-**help> >>>>>> <http**s://stat.ethz.ch/mailman/**listinfo/r-help<https://stat.ethz.ch/mailman/listinfo/r-help> >>>>>> > >>>>>> PLEASE do read the posting guide http://www.R-project.org/** >>>>>> posting-guide.html<http://www.****R-project.org/posting-guide.** >>>>>> **html<http://www.R-project.**org/posting-guide.html<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.