I want to take slices of a multi-dimensional table (or array) without knowing the number of dimensions in advance. As a test I tried using (in this example a 3d table): do.call(`[`, list(tbl, x,NULL,NULL)] where I built the list on the fly. It works great as long as I only want the first dimension however when I try a different dimension, say with list(tbl,NULL,x,NULL), I get "<0 x 0> matrix" as the result. I thought this was because I wasn't calling the right function but there is no `[.table` or `[.matrix` or even `[.array`. Am I going about this the wrong way? DAV [[alternative HTML version deleted]]
On Thu, Dec 22, 2011 at 4:34 AM, David A Vavra <davavra at verizon.net> wrote:> I want to take slices of a multi-dimensional table (or array) without > knowing the number of dimensions in advance. > > > > As a test I tried using (in this example a 3d table): > > > > ? ? do.call(`[`, list(tbl, x,NULL,NULL)] > > > > where I built the list on the fly. It works great as long as I only want the > first dimension however when I try a different dimension, say with > list(tbl,NULL,x,NULL), I get "<0 x 0> matrix" as the result. I thought this > was because I wasn't calling the right function but there is no `[.table` or > `[.matrix` or even `[.array`. > > > > Am I going about this the wrong way?>From help("[", package="base"): "An index value of NULL is treated asif it were integer(0).".> y <- array(1:24, dim=c(2,3,4)) > dimnames(y)[[1]] <- sprintf("a%d", 1:dim(y)[1]) > dimnames(y)[[2]] <- sprintf("b%d", 1:dim(y)[2]) > dimnames(y)[[3]] <- sprintf("c%d", 1:dim(y)[3]) > y[NULL,2:3,1,drop=FALSE], , c1 b2 b3> y[integer(0),2:3,1,drop=FALSE], , c1 b2 b3 I don't think there is an easy way to achieve:> y[,2:3,1,drop=FALSE], , c1 b2 b3 a1 3 5 a2 4 6 using do.call("[") without explicitly specify the indices for that "missing" dimension, i.e.> y[seq(length=dim(y)[1]),2:3,1,drop=FALSE], , c1 b2 b3 a1 3 5 a2 4 6 If you're willing to use R.utils you can do: library("R.utils");> extract(y, indices=list(2:3,1), dims=c(2,3), drop=TRUE);b2 b3 a1 3 5 a2 4 6 My $.02 /Henrik> > > > DAV > > > > > ? ? ? ?[[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.
On Dec 21, 2011, at 10:34 PM, David A Vavra wrote:> I want to take slices of a multi-dimensional table (or array) without > knowing the number of dimensions in advance. > > As a test I tried using (in this example a 3d table): > > do.call(`[`, list(tbl, x,NULL,NULL)]Surely that was meant to be: do.call(`[`, list(tbl, x,NULL,NULL) ) (This does imply you knew the number of dimensions was 3.)> > where I built the list on the fly. It works great as long as I only > want the > first dimension however when I try a different dimension, say with > list(tbl,NULL,x,NULL), I get "<0 x 0> matrix" as the result. I > thought this > was because I wasn't calling the right function but there is no > `[.table` or > `[.matrix` or even `[.array`.It is interesting to look at what that returns. tbl <- array(1:27, c(3,3,3)) x=1 str( do.call(`[`, list(tbl, x,NULL,NULL) ) ) int[1, 0 , 0 ] It looks as though the Nulls became 0's. So if you wanted to use do.call(`[` then this succeeds: > do.call(`[`, list(tbl, x, 1:dim(tbl)[2], 1:dim(tbl)[3]) ) [,1] [,2] [,3] [1,] 1 10 19 [2,] 4 13 22 [3,] 7 16 25 As does this using the "empty comma" approach: eval(parse(text= paste("tbl[ " ,x, " , , ]")) ) [,1] [,2] [,3] [1,] 1 10 19 [2,] 4 13 22 [3,] 7 16 25 (Which after looking at the `r.utils::extract` code suggested by Bengtsson, was what he did .... after considerably better sanity checking than above.)> > Am I going about this the wrong way? > > DAV > > [[alternative HTML version deleted]]-- David Winsemius, MD West Hartford, CT