Hello people, Is there some simple way of spinning and/or flipping arrays in R? Here's what I mean. Suppose that foo is a 2x3x4 array with the following contents: (I know this is different than typing 'foo' at and R prompt, but I'm so used to row major order from using APL, I have a hard time with R's output)> foo[1,,][,1] [,2] [,3] [,4] [1,] 1 2 3 4 [2,] 5 6 7 8 [3,] 9 10 11 12> foo[2,,][,1] [,2] [,3] [,4] [1,] 13 14 15 16 [2,] 17 18 19 20 [3,] 21 22 23 24 flipping foo around its last coordinate would be done via> flipfoo <- foo[,,4:1]> flipfoo[1,,][,1] [,2] [,3] [,4] [1,] 4 3 2 1 [2,] 8 7 6 5 [3,] 12 11 10 9> flipfoo[2,,][,1] [,2] [,3] [,4] [1,] 16 15 14 13 [2,] 20 19 18 17 [3,] 24 23 22 21 (a more general method would allow specifying the axis around which to reverse the subscripts) spinning corresponds to shifting the coordinates by possibly different amounts along one axis. I need these to manipulate a dataset, and have been tearing my hair out for a day and a half trying to figure out how to do it in R. Matlab has a few user-written utilities. APL has it built in as an operator. R *should* be able to do it, but I'm too new to R to figure it out. It could be easily done in general by any number of ways if only I could figure out how to turn a string (like ",,4:1") into the argument for "[". Nothing I've tried or searched for works, but I suspect I'm being a bit obtuse. Thanks for any and all hints. Bill
I know of no single function to do this; perhaps someone else does. I don't have time to write and debug functions to do this myself, but it should be easy enough to write functions like the following: flip3 <- function(x){ n3 <- dim(x)[3] x[,,n3:1] } spin3 <- function(x, k=1){ n3 <- dim(x)[3] x[,,1+(((1+k):(n3+k))%%n3)] } With a little more work, I could generate functions that would do this for any dimension of arrays with any number of dimensions. To do that, I might have to compute S-Plus commands using "cmd <- paste(...)" and then execute them using "eval(parse(text=cmd))". Perhaps someone else will reply with a more complete and elegant solution. Until then, I hope this helps. spencer graves Bill Rising wrote:> Hello people, > > Is there some simple way of spinning and/or flipping arrays in R? > Here's what I mean. > > Suppose that foo is a 2x3x4 array with the following contents: (I know > this is different than typing 'foo' at and R prompt, but I'm so used to > row major order from using APL, I have a hard time with R's output) > > >>foo[1,,] > > [,1] [,2] [,3] [,4] > [1,] 1 2 3 4 > [2,] 5 6 7 8 > [3,] 9 10 11 12 > > >>foo[2,,] > > [,1] [,2] [,3] [,4] > [1,] 13 14 15 16 > [2,] 17 18 19 20 > [3,] 21 22 23 24 > > flipping foo around its last coordinate would be done via > > >>flipfoo <- foo[,,4:1] > > >>flipfoo[1,,] > > [,1] [,2] [,3] [,4] > [1,] 4 3 2 1 > [2,] 8 7 6 5 > [3,] 12 11 10 9 > >>flipfoo[2,,] > > [,1] [,2] [,3] [,4] > [1,] 16 15 14 13 > [2,] 20 19 18 17 > [3,] 24 23 22 21 > > (a more general method would allow specifying the axis around which to > reverse the subscripts) > > spinning corresponds to shifting the coordinates by possibly different > amounts along one axis. > > I need these to manipulate a dataset, and have been tearing my hair out > for a day and a half trying to figure out how to do it in R. Matlab has a > few user-written utilities. APL has it built in as an operator. R > *should* be able to do it, but I'm too new to R to figure it out. It > could be easily done in general by any number of ways if only I could > figure out how to turn a string (like ",,4:1") into the argument for "[". > Nothing I've tried or searched for works, but I suspect I'm being a bit > obtuse. > > Thanks for any and all hints. > > Bill > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://www.stat.math.ethz.ch/mailman/listinfo/r-help
On 5/26/2003 15:05, Spencer Graves wrote> I know of no single function to do this; perhaps someone else does. > I don't have time to write and debug functions to do this myself, but >it should be easy enough to write functions like the following: > >flip3 <- >function(x){ > n3 <- dim(x)[3] > x[,,n3:1] >} >spin3 <- >function(x, k=1){ > n3 <- dim(x)[3] > x[,,1+(((1+k):(n3+k))%%n3)] >}These are pretty much what I'd figured out...> >With a little more work, I could generate functions that would do this >for any dimension of arrays with any number of dimensions. To do that, >I might have to compute S-Plus commands using "cmd <- paste(...)" and >then execute them using "eval(parse(text=cmd))".This last piece is what I think I needed. I had been trying to just put the /argument/ to the "[" command together, instead of putting together the entire command. Thanks for the tip. I'll keep working on it. Bill
On 5/26/2003 17:21, Peter Dalgaard BSA wrote>Bill Rising <brising at louisville.edu> writes: > >> On 5/26/2003 15:05, Spencer Graves wrote >>[snip...] This seems to work for the flipping (and it relies on textual representations, and is completely unreadable, and is inelegant): fliparr <- function(arr,dims=length(dim(arr))) { #defaults to flipping across last dimension, otherwise takes # a vector of dimensions (which ignores dimesions which are out of bounds) # NO error checking yet # initialize a series of blank strings for the indices strarg <- vector("character",arrsize <- length(arrdim<-dim(arr))) # find which indices will be flipped (logical vector) which <- apply(outer(1:arrsize,as.vector(dims),"=="),1,any) # use 1:dimension size for non-flipped dimensions strarg[!which] <- paste(NULL,arrdim[!which],sep="1:") # use dimension size:1 for flipped dimensions strarg[which] <- paste(arrdim[which],NULL,sep=":1") # paste all the text together and hope syntax never changes eval(parse(text=paste("arr[",paste(strarg,collapse=","),"]",collapse=""))) }> >Relying on textual representation always looks dodgy to me.You've got a good point.>How about > >spin <- function(x,amount=c(1,rep(0,length(dim(x))-1))) { > indices <- mapply(function(n,k) (seq(length=n)+k-1)%%n + 1, > dim(x),amount, SIMPLIFY=FALSE) > do.call("[", c(list(x), indices)) >}This works quite well for spinning an equal amount in each dimension. I think I can use this to work on the equivalent to APL which either uses a single number to spin a single dimension (like spin(foo,c(something,0,0)) ) or an array with the dimensions of the original array minus the dimension around which items are spun, so that the items can be shifted differenent amounts.> >(Note: mapply() was introduced in 1.7.0).I'll check out mapply. thanks, Bill
On Mon, 26 May 2003, Bill Rising wrote:> Hello people, > > Is there some simple way of spinning and/or flipping arrays in R? > Here's what I mean. >I don't think there's a built-in solution. I would try constructing the permutation of indices, probably using aperm() to move the index of interest to first or last place, whichever is easiest. This sort of thing might well be worth coding at least partly in C. -thomas