Skip to content

Wish (PR#3690)

4 messages · a.buness@dkfz.de, Peter Dalgaard, Patrick Burns +1 more

#
Full_Name: Andreas Buness
Version: 1.7.1
OS: Unix
Submission from: (NULL) (193.174.53.122)


I would like to ask you to enhance the apply function
with an option drop=FALSE similar to the one existing
for subsetting of arrays. Or any other mechanism to get
control on the dimensionality of an object resulting 
from an apply call. This could facilitate more robust 
programming.
#
a.buness@dkfz.de writes:
Don't you mean simplify=TRUE similar to sapply()? This has been
suggested a couple of times. Or how do you intend 'drop' to work?
#
I'm not sure if this is the original wish or not, but I have run
into the following situation:

I apply a function to a matrix, but the operation fails because
the function expects a matrix (which in my mind is the one
column or row at each go). The function doesn't see it that
way because it only gets the data as a vector.

Personally, I'd favor forcing the user to write a wrapper function
that does as.matrix (possibly with a transpose) rather than cluttering
up apply.  

Patrick Burns

Burns Statistics
patrick@burns-stat.com
+44 (0)20 8525 0696
http://www.burns-stat.com
(home of S Poetry and "A Guide for the Unwilling S User")
Peter Dalgaard BSA wrote:

            
2 days later
#
When I want apply() to always return a matrix, no matter whether the 
returned value from the applied function is a single value or a 
multi-element vector, I often use rbind() or cbind() along the lines of the 
following:

 > # Some example data:
 > x <- rbind(1:3,7:9)
 > x
      [,1] [,2] [,3]
[1,]    1    2    3
[2,]    7    8    9

 > # The problem -- different shaped result depending on whether the 
applied function returns a single value or a matrix:
 > apply(x, 1, min)
[1] 1 7
 > apply(x, 1, c)
      [,1] [,2]
[1,]    1    7
[2,]    2    8
[3,]    3    9
 >

 > # A solution:
 > do.call("rbind", unlist(apply(x, 1, function(row) list(row)), rec=F))
      [,1] [,2] [,3]
[1,]    1    2    3
[2,]    7    8    9
 > do.call("rbind", unlist(apply(x, 1, function(row) list(min(row))), rec=F))
      [,1]
[1,]    1
[2,]    7
 >
 > # Beware that the above manner of calling apply() can preclude some 
potential optimizations that could otherwise be performed by the 
implementation of apply() (but, as far as I am aware, these are not 
performed in the current version of R).

There would be of course many other ways of ensuring that your result is of 
a particular shape, some possibly more efficient, e.g., using matrix() with 
the appropriate nrow or ncol arguments.

It would be difficult to add any new arguments to apply() because apply() 
passes arguments it doesn't recognize down the supplied function.  If a new 
argument were added to apply(), especially one with a common name like 
drop, that could break existing code that depended on that argument being 
passed to the applied function.  It would probably make more sense to add 
to the apply() family a new function that was designed to work in a regular 
way with arrays with any number of dimensions, and I'm sure there would be 
many opinions on what features that function should have (I would argue 
that it should preserve the ordering of dimensions so that, for instance, 
the call analogous to apply(x, 1, c) returned x rather than the transpose 
of x.)

-- Tony Plate
At Friday 03:50 PM 8/8/2003 +0200, a.buness@dkfz.de wrote: