Anuj Amin
Anuj Amin

Reputation: 77

How to convert the tapply function into a for loop?

I have a function that is supposed to work like tapply() but I can't seem to get it working right. I need to use a for loop this.

baby.tapply = function(X, INDEX, FUN) {
  z = 0
 for(y in levels(factor(INDEX))){
   z = FUN(X)
 }
  return(z)
}

baby.tapply(X=mtcars$mpg, INDEX=mtcars$cyl, FUN=mean)

#Should mimic this: 
tapply(mtcars$mpg, mtcars$cyl, mean)

Any suggestions from where to go from here? My output: 20.090625 1

Correct Output (from tapply) 4 6 8 26.66364 19.74286 15.10000

Upvotes: 1

Views: 254

Answers (1)

Ronak Shah
Ronak Shah

Reputation: 388982

Here's one way to mimic tapply with for loop :

baby.tapply = function(X, INDEX, FUN) {

  lvls <- levels(factor(INDEX))
   z <- numeric(length(lvls))
   for(y in seq_along(lvls)){
       z[y] = FUN(X[INDEX == lvls[y]])
    }
    return(setNames(z, lvls))
}

baby.tapply(X=mtcars$mpg, INDEX=mtcars$cyl, FUN=mean)
#      4        6        8 
#26.66364 19.74286 15.10000 

#Comparing with the output of tapply
tapply(mtcars$mpg, mtcars$cyl, mean)
#       4        6        8 
#26.66364 19.74286 15.10000 

As mentioned by @Onyambu probably it is better to initialize z as list and not a vector

z <- vector("list",length(lvls))

for functions such as range which return two values.

Upvotes: 2

Related Questions