Skip to content

make apply() return a list

4 messages · Arne Henningsen, Gabor Grothendieck

#
Hi,

thank you very much Sundar, Patrick, Tony, Mahub and Gabor for your helpful 
answers! All your examples work great. They are all more straightforeward 
than my example and much faster than the for-loop. 
These are the average elapsed times (in seconds) returned by system.time()[3] 
(applied to my real function and my real data):

my original for-loop: 
5.55 

the example I presented in my previous email (using apply):
2.35 

example suggested by Tony (using apply):
2.34 

example suggested by Gabor (using lapply):
2.50 

examples suggested by Sundar and Mahub (using lapply):
2.68 

Best regards,
Arne
On Monday 01 November 2004 19:52, Sundar Dorai-Raj wrote:

  
    
#
Arne Henningsen <ahenningsen <at> email.uni-kiel.de> writes:

: 
: Hi,
: 
: thank you very much Sundar, Patrick, Tony, Mahub and Gabor for your helpful 
: answers! All your examples work great. They are all more straightforeward 
: than my example and much faster than the for-loop. 
: These are the average elapsed times (in seconds) returned by system.time()
[3] 
: (applied to my real function and my real data):
: 
: my original for-loop: 
: 5.55 
: 
: the example I presented in my previous email (using apply):
: 2.35 
: 
: example suggested by Tony (using apply):
: 2.34 
: 
: example suggested by Gabor (using lapply):
: 2.50 
: 
: examples suggested by Sundar and Mahub (using lapply):
: 2.68 
: 


Perhaps any comparison should also include simplicity.  This is
somewhat subjective but just to objectify it I have reworked
each solution to compactify it as much as I could and then
calculated the number of characters in each solution using wc:

AH - 293 characters
TP - 70 characters
ML - 62 characters
GG - 48 characters

The versions I used are below.  

---

# data
myData <- data.frame( a = c( 1,2,3 ), b = c( 4,5,6 ) )

# AH
myFunction <- function( values ) {
   myMatrix <- matrix( values, 2, 2 )
   if( all( values == myData[ 1, ] ) ) {
      myMatrix <- cbind( myMatrix, rep( 0, 2 ) )
   }
   return( myMatrix )
}
myList <- apply( myData, 1, myFunction )
myList[[ 1 ]] <- myList[[ 1 ]][ 1:2, 1:2 ]
myList

# TP
lapply(apply(myData, 1, function(x) list(matrix(x, 2, 2))), "[[", 1)

# ML
lapply(1:nrow(myData), function(i) matrix(myData[i,], 2, 2))

# GG
lapply(as.data.frame(t(myData)), matrix, 2, 2)
#
On Tuesday 02 November 2004 15:29, Gabor Grothendieck wrote:
Yes, you are totally right!
Thank you for wotking this out. I was also thinking about simplicity when I 
compared the different suggestions. Finally I took Tonys suggestion although 
the code is a bit longer than the others in _your_ comparison. The reason was 
only partially the speed, but compared to ML and GG this code preserves the 
(col)names of the dataframe, which I need in the real "myFunction". 
Circumventing this small problem in ML's and GG's suggestions would make my 
code (a bit) longer than the code based on TP's suggestion.

Best wishes,
Arne

  
    
#
Arne Henningsen <ahenningsen <at> email.uni-kiel.de> writes:

:
: On Tuesday 02 November 2004 15:29, Gabor Grothendieck wrote:
: > Arne Henningsen <ahenningsen <at> email.uni-kiel.de> writes:
: > : Hi,
: > :
: > : thank you very much Sundar, Patrick, Tony, Mahub and Gabor for your
: > : helpful answers! All your examples work great. They are all more
: > : straightforeward than my example and much faster than the for-loop.
: > : These are the average elapsed times (in seconds) returned by
: > : system.time()
: >
: > [3]
: >
: > : (applied to my real function and my real data):
: > :
: > : my original for-loop:
: > : 5.55
: > :
: > : the example I presented in my previous email (using apply):
: > : 2.35
: > :
: > : example suggested by Tony (using apply):
: > : 2.34
: > :
: > : example suggested by Gabor (using lapply):
: > : 2.50
: > :
: > : examples suggested by Sundar and Mahub (using lapply):
: > : 2.68
: >
: > Perhaps any comparison should also include simplicity.  
: 
: Yes, you are totally right!
: 
: > This is 
: > somewhat subjective but just to objectify it I have reworked
: > each solution to compactify it as much as I could and then
: > calculated the number of characters in each solution using wc:
: >
: > AH - 293 characters
: > TP - 70 characters
: > ML - 62 characters
: > GG - 48 characters
: 
: Thank you for wotking this out. I was also thinking about simplicity when I 
: compared the different suggestions. Finally I took Tonys suggestion although 
: the code is a bit longer than the others in _your_ comparison. The reason 
was 
: only partially the speed, but compared to ML and GG this code preserves the 
: (col)names of the dataframe, which I need in the real "myFunction". 
: Circumventing this small problem in ML's and GG's suggestions would make my 
: code (a bit) longer than the code based on TP's suggestion.

Note that neither the problem statement nor your example code
showing what the solution should look like (nor my compactified versions 
of the responses) exhibit colnames.

: 
: Best wishes,
: Arne
: 
: > The versions I used are below.
: >
: > ---
: >
: > # data
: > myData <- data.frame( a = c( 1,2,3 ), b = c( 4,5,6 ) )
: >
: > # AH
: > myFunction <- function( values ) {
: >    myMatrix <- matrix( values, 2, 2 )
: >    if( all( values == myData[ 1, ] ) ) {
: >       myMatrix <- cbind( myMatrix, rep( 0, 2 ) )
: >    }
: >    return( myMatrix )
: > }
: > myList <- apply( myData, 1, myFunction )
: > myList[[ 1 ]] <- myList[[ 1 ]][ 1:2, 1:2 ]
: > myList
: >
: > # TP
: > lapply(apply(myData, 1, function(x) list(matrix(x, 2, 2))), "[[", 1)
: >
: > # ML
: > lapply(1:nrow(myData), function(i) matrix(myData[i,], 2, 2))
: >
: > # GG
: > lapply(as.data.frame(t(myData)), matrix, 2, 2)