[R] Access only part of last dimension of table/matrix

Marc Schwartz marc_schwartz at me.com
Sat Jul 2 03:29:24 CEST 2011


On Jul 1, 2011, at 8:15 PM, David Winsemius wrote:

> 
> On Jul 1, 2011, at 7:44 PM, Marc Schwartz wrote:
> 
>> On Jul 1, 2011, at 4:50 PM, David Winsemius wrote:
>> 
>>> 
>>> I would like to do some operations inside a function using only one value for the last dimension of a table/matrix:
>>> 
>>> tabfn <- function (dfrm, facvec, YN ="event"){
>>>           return( Etbl <- do.call(table, dfrm[ , c(facvec, "event") ]) )
>>>            # just want Etbl[,,,"TRUE"] or Etbl[,, "TRUE"] or Etbl[,"TRUE"]
>>>            }
>>> tbl <- tabfn(testdf, c("x", "y") )
>>> tbl   # all value of event returned
>>> 
>>> At the console it is easy for me to count the number of factors and use the right number of commas
>>> 
>>> tbl[ , , "TRUE"] if I only want the slice with that value. How can I do this programmatically?
>>> 
>>> Thnks.
>> 
>> 
>> David,
>> 
>> I had a vague recollection of something like this coming up at some point in the past and it took me a bit to get the right keywords to find it.
>> 
>> I did not realize how far back it was (2001), but here are two possible solutions by Peter Dalgaard and Thomas Lumley from the same thread:
>> 
>> https://stat.ethz.ch/pipermail/r-help/2001-October/016110.html
>> https://stat.ethz.ch/pipermail/r-help/2001-October/016122.html
>> 
>> It looks like Peter's solution is along the lines of the one that you just posted.
> 
> 
> Yeah. Thanks, Mark. Pretty much the same. Guess I'm in good company. (Surprised this isn't asked more frequently.)
> 
> testdf <- data.frame(x=sample(letters[1:5], 25, replace=TRUE),
>                    y=sample(letters[1:5], 25, replace=TRUE),
>                    z=sample(letters[1:5], 25, replace=TRUE),
>                    event=sample(c(TRUE, FALSE), 25, replace=TRUE) )
> 
> etbl <- table(testdf[ , c(c("x", "y"), "event")])
> apply(etbl, seq(length=length(dim(etbl))-1),"[", 2)  # Dalgaard 2001
> apply(etbl, 1:(length(dim(etbl))-1), "[", 2)   # Winsemius 2011
> 
> Any idea how to make it a "selection"? By that I mean how to select values of the last dimension whose "event" values are "TRUE". I get "Error: object 'event' not found" with any expression involving event, since it is only an attribute in dimnames.
> 
> 
>> 
>> Hope that this helps.
> 
> Yes. At least there is nothing (yet) that I would call "truly elegant". Maybe it's just that I stumbled on my solution, rather than seeing it as a glaringly obvious application of apply(..., "[" , index)
> 
>> 
>> Regards,
> 
> Sorry for the duplicate private message. Meant to hit reply to all.


Not a problem David, I was just in the process of replying to it when I saw this reply.

Try this:

> apply(etbl, seq(length=length(dim(etbl))-1), function(x) x["TRUE"])
   y
x   a b c d e
  a 0 1 1 0 0
  b 1 0 0 1 0
  c 0 0 0 0 0
  d 1 0 0 0 2
  e 0 1 0 1 0


Seems to work here, at least on your example data, but not fully tested on higher dimensional arrays.

I also tried it on the UCBAdmissions data set:

> str(UCBAdmissions)
 table [1:2, 1:2, 1:6] 512 313 89 19 353 207 17 8 120 205 ...
 - attr(*, "dimnames")=List of 3
  ..$ Admit : chr [1:2] "Admitted" "Rejected"
  ..$ Gender: chr [1:2] "Male" "Female"
  ..$ Dept  : chr [1:6] "A" "B" "C" "D" ...


Get Dept == "C":

> apply(UCBAdmissions, seq(length=length(dim(UCBAdmissions))-1), function(x) x["C"])
          Gender
Admit      Male Female
  Admitted  120    202
  Rejected  205    391


It actually scared me that I had any recollection of an isolated post from 10 years ago. Not sure what to make of that...

Regards,

Marc



More information about the R-help mailing list