An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20111221/a119318f/attachment.pl>
Indexing multi-dimensional table
7 messages · Henrik Bengtsson, David Winsemius, davavra +2 more
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 as
if 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
(This does imply you knew the number of dimensions was 3.)
Yes, at run time.
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]) )
...
As does this using the "empty comma" approach:
eval(parse(text= paste("tbl[ " ,x, " , , ]")) )
I tried the eval course but that struck me as slower. Perhaps not? It's not that I'm set on using '['. I was under the impression that was how the eval expression is eventually parsed. I also thought the empty commas were eventually passed as NULLs. Wasn't aware of the 'str' function. Could come in handy down the road. Thanks. DAV
From help("[", package="base"): "An index value of NULL is treated as
if it were integer(0).".
Yeah, I should have read it better.
I don't think there is an easy way to achieve:
y[,2:3,1,drop=FALSE]
using do.call("[") without explicitly specify the indices for that
"missing" dimension, i.e.
...
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);
Thanks, Henrik. I also wasn't aware of R.utils until today. I should do more reading :) DAV -- View this message in context: http://r.789695.n4.nabble.com/Indexing-multi-dimensional-table-tp4224543p4226198.html Sent from the R help mailing list archive at Nabble.com.
Continuing the annnoying tradition of partial quotes:
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]
You can build the 2nd argument to do.call with alist() instead
of list() to send missing arguments to the function given as
the 1st argument. E.g. to extract the first row, as a row matrix,
from the matrix state.x77 you usually do
> state.x77[1, , drop=FALSE]
Population Income Illiteracy Life Exp Murder HS Grad Frost Area
Alabama 3615 3624 2.1 69.05 15.1 41.3 20 50708
and here are some unsucessful attempts to do it with do.call("[",...)
using list()):
> do.call("[", list(state.x77, 1, ,drop=FALSE)) # bad
Error in list(state.x77, 1, , drop = FALSE) : argument 3 is empty
> do.call("[", list(state.x77, 1, drop=FALSE))
[1] 3615
and a to do it with alist:
> do.call("[", alist(state.x77, 1, ,drop=FALSE))
Population Income Illiteracy Life Exp Murder HS Grad Frost Area
Alabama 3615 3624 2.1 69.05 15.1 41.3 20 50708
alist() produces a list that you can use c() and subscripting on
to add or modify arguments. It is usually better to encapsulate
this sort of thing in a function like extract() that has a convenient
interface.
Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
-----Original Message----- From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of davavra Sent: Thursday, December 22, 2011 10:31 AM To: r-help at r-project.org Subject: Re: [R] Indexing multi-dimensional table
From help("[", package="base"): "An index value of NULL is treated as
if it were integer(0).".
Yeah, I should have read it better.
I don't think there is an easy way to achieve:
y[,2:3,1,drop=FALSE]
using do.call("[") without explicitly specify the indices for that
"missing" dimension, i.e.
...
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);
Thanks, Henrik. I also wasn't aware of R.utils until today. I should do more reading :) DAV -- View this message in context: http://r.789695.n4.nabble.com/Indexing-multi-dimensional-table- tp4224543p4226198.html Sent from the R help mailing list archive at Nabble.com.
______________________________________________ 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.
From: William Dunlap [mailto:wdunlap at tibco.com] You can build the 2nd argument to do.call with alist() instead. alist() produces a list that you can use c() and subscripting on to add or modify arguments. It is usually better to encapsulate this sort of thing in a function like extract() that has a convenient interface.
Thanks. alist seems to produce empty list entries for missing arguments. It wasn't clear to me how to generate one at run time. For example, how does one append an empty list element? c(x,) produces "argument 2 is empty". However I've discovered c(alist(x,y),alist(),alist(z)) produces an empty entry between y and z. This will likely fit better in the code I currently have.
Continuing the annoying tradition of partial quotes
A matter of taste, I guess. Speaking strictly for myself, I am annoyed by needless repetition (particularly of mostly irrelevant matter such as output, signature tags, subject name, to/from lines and quotes of quotes of quotes) not to mention the tedium of such in a long reply stream making it hard sometimes to locate the relevant replies. Omitting the things I've listed perforce means a partial quote. DAV