[R] Inflate/Expand/Resize an array

Mark Payne mpa at difres.dk
Mon Apr 30 13:41:13 CEST 2007


Gudday,

Robin's reply obviously set something in motion in my brain, because I woke up with the answer on Saturday morning (which was actually pretty frustrating because I had to wait until Monday morning to try it out!) - essentially create a dummy array of 1s, and then use sweep to fill it out... Here's my code for the general solution...

### FnInflate
### ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
#Inflates an input array of arbitray size along the necessary dimensions to achieve the
#same size as that in target.dim
#balloon    :   array to be "inflated"
#target.dim :   final size of "balloon". NB target.dim and balloon must have the same NUMBER of dimensions...

FnInflate     <-  function(balloon, target.dim) {
  #Check number of input dimensions
  dim.balloon     <-  dim(balloon)
  if(length(target.dim)!=length(dim.balloon)) {
    stop("Input array does not have the same dimensionality as indicated in target.dim.")
  }
  #Identify the dimensions along which to inflate the array
  same.dims               <-  dim.balloon == target.dim             #A boolean array indicating whether the arrays correspond in that dimension
  corresponding.dims      <-  (1:length(target.dim))[same.dims]     #Dimensions that correspond between the target dim and the input array
  non.corresponding.dims  <-  (1:length(target.dim))[!same.dims]     #Dimensions that do not correspond between the target dim and the input array
  #Check that the non-corresponding dimensions are all of size 1 in the input array - we don't know what to do if this is not the case
  if(prod(dim(balloon)[non.corresponding.dims] == 1)==FALSE) {
    stop("Input array not suitable for inflation as non-corresponding dimensions are not of size 1.")
  }
  #Create temp array of 1s
  inflated.balloon  <-  array(1,dim=target.dim)
  #And inflate using sweep
  inflated.balloon  <-  sweep(inflated.balloon, corresponding.dims, balloon, "*")
  #Return results
  return(inflated.balloon)
}

Here's an example of it in use, inflating f along dimensions 2 and 6 to give a result the same size as N.

> dim(f)
[1] 10  1  1  1  1  1
> dim(N)
[1] 10 25  1  1  1  6
> dim(FnInflate(f,dim(N)))
[1] 10 25  1  1  1  6

Its written to solve the general problem, as you see here. Note that it will throw its hands up in the air if you try to inflate a (5,1,1) array to a (10,1,1) array - it will only work for, for example, inflating (5,1,1) to (5,10,10).

Thanks to all for their comments.

Cheers,

Mark


> -----Original Message-----
> From: Robin Hankin [mailto:r.hankin at noc.soton.ac.uk] 
> Sent: Friday, 27 April 2007 13:32
> To: Robin Hankin
> Cc: Mark Payne; r-help at stat.math.ethz.ch
> Subject: Re: [R] Inflate/Expand/Resize an array
> 
> [replying to myself]
> 
> it might be better to use
> 
> sweep(f,(1:6)[-2],m,"+")
> 
> instead.
> 
> 
> 
> 
> On 27 Apr 2007, at 11:56, Robin Hankin wrote:
> 
> > Hi
> >
> >
> >   f.dims <- c(10,25,1,1,1,14)
> >   m.dims <- c(10, 1,1,1,1,14)
> >   f <- array(1:prod(f.dims),f.dims)
> >   m <- array(1:prod(m.dims),m.dims)
> >   jj <- do.call(abind,c(rep(list(m),25),along=2))
> >
> >
> > Then
> >
> > f + jj
> >
> > will give you what you want.
> >
> >
> > The more general problem is a bit harder, as you say....
> >
> >
> > HTH
> >
> > rksh
> >
> >
> > On 27 Apr 2007, at 10:41, Mark Payne wrote:
> >
> >> Gudday,
> >>
> >> I've had a good look everywhere trying to figure out how 
> to do this, 
> >> but I'm afraid I can seem to find an answer anywhere - maybe its 
> >> because I'm not using the right terms, or maybe its because I'm a 
> >> dummy. But unfortunately, I am not completely and utterly stuck. 
> >> Here's the
> >> problem:
> >>
> >> I have two large, six dimensional arrays that I would like to add 
> >> together. Lets call them f and m. Their dimensions are 
> respectively:
> >>
> >>> dim(f)
> >> [1] 10  25  1  1  1 14
> >>> dim(m)
> >> [1] 10 1 1 1 1 14
> >>
> >> You can see that they're pretty close in size, but not identical.
> >> What I
> >> would like to do is expand or inflate m along its second 
> dimension so 
> >> that it ends up with dimension 10 25 1 1 1 14, so that I 
> can then add 
> >> the two together - the new values created along that 
> second dimension 
> >> would simply be copies of the first value..
> >>
> >> What's the fastest way to do this? Is there a dedicated function?
> >> Ideally I envisage something that you feed the input 
> array, and the 
> >> desired dimensions, and it does the rest for you. Please 
> also bear in 
> >> mind that this is a specific problem - the more general 
> case is where 
> >> I don't know which dimensions are "out of shape", so to speak...
> >>
> >> I hope that's clear, and that someone can me out here...
> >>
> >> Cheers,
> >>
> >> Mark
> >>
> >> ______________________________________________
> >> 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.
> >
> > --
> > Robin Hankin
> > Uncertainty Analyst
> > National Oceanography Centre, Southampton European Way, Southampton 
> > SO14 3ZH, UK
> >   tel  023-8059-7743
> >
> > ______________________________________________
> > 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.
> 
> --
> Robin Hankin
> Uncertainty Analyst
> National Oceanography Centre, Southampton European Way, 
> Southampton SO14 3ZH, UK
>   tel  023-8059-7743
> 
> 
> 
>



More information about the R-help mailing list