Skip to content
Back to formatted view

Raw Message

Message-ID: <1101235677.21009.27.camel@horizons.localdomain>
Date: 2004-11-23T18:47:57Z
From: Marc Schwartz
Subject: IFELSE across large array?
In-Reply-To: <3A822319EB35174CA3714066D590DCD50994E36F@usrymx25.merck.com>

On Tue, 2004-11-23 at 12:28 -0500, Liaw, Andy wrote:
> I'll give it half a crack:
> 
> Steps a through c can be done via nested ifelse(), treating A and M as
> vectors (as they really are).  Step d is the hard one.  I'd write a simple
> Fortran code and use .Fortran() for that.
> 
> I don't see how any of the *apply() functions can help here, as your
> operations are element-wise, not dimension-wise.
> 
> Andy

I'll toss in one additional thought here in follow up to Andy's, which
is that you could feasibly use mapply() to do element-wise operations. 

In fact, this is how I compute concordant and discordant pairs in a 2D
matrix for some of the measures of association that I want to include in
the CrossTable() function in the gregmisc bundle.

I'll paste the code for the concordant() function here, to give you an
idea of the approach:

# Calculate CONcordant Pairs in a table
# cycle through x[r, c] and multiply by
# sum(x elements below and to the right of x[r, c])
# x = table
concordant <- function(x)
{
  # get sum(matrix values > r AND > c)
  # for each matrix[r, c]
  mat.lr <- function(r, c)
  { 
    lr <- x[(r.x > r) & (c.x > c)]
    sum(lr)
  }

  # get row and column index for each
  # matrix element
  r.x <- row(x)
  c.x <- col(x)

  # return the sum of each matrix[r, c] * sums
  # using mapply to sequence thru each matrix[r, c]
  sum(x * mapply(mat.lr, r = r.x, c = c.x))
}


Presumably, you could extend the basic approach to a 3D structure, by
using a third index argument to the mapply() call and use something like
expand.grid() to create the three vectors for the indices into the 3D
array:

# Set up the index combinations for a 4 x 4 x 4 array
Index <- expand.grid(1:4, 1:4, 1:4)

YourFunction <- function(a, b, c)
{
   DoSomethingHere(YourArray[a, b, c])
}

YourReturnVals <- mapply(YourFunction, a = Index[, 1], b = Index[, 2], 
                         c = Index[, 3])


I am hoping that this approach might be applicable here, at least in
basic concept.  Also, keep in mind any scoping issues with respect to
your data structures.

HTH,

Marc Schwartz