Irshad
Irshad

Reputation: 61

How to store in-built function names in a Vector and parse through a loop in R

I am new to R and need some help.

I want to calculate the mean, median, etc. through a For Loop, for every column in the dataframe df. These functions are stored in vector my_func. I am not able to convert the variable stored in vector my_func to excute the function which is intended. I am adding the stats to the bottom of the dataframe:

my_func=c("mean", "median", "stats::sd", "max", "min")

for (func in my_func){
  new_row <- c()

  for (i in names(df)){
    y <- func(df[ ,i], na.rm=F)
    new_row <- c(new_row, y)
  }
  df[nrow(df)+ 1, ] = c(new_row[1:11])
  rownames(df)[nrow(df)] <- j
}

Upvotes: 1

Views: 69

Answers (2)

user2554330
user2554330

Reputation: 44937

Storing the functions as suggested by @KarolisKoncevicius is probably the best solution, but another way to do it is to retrieve the functions by name before calling them. Since one of your functions is defined by the expression stats::sd rather than just the name, you should parse the expression and use eval() to get the functions.

Your sample code also has a couple of other problems: it refers to j without defining it, and it assumes there are 11 entries in new_row, when there could be any number. This code fixes both problems and shows the parse and eval solution:

df <- data.frame(x = 1:10, y = rnorm(10))

my_func=c("mean", "median", "stats::sd", "max", "min")

for (func in my_func){
  new_row <- c()
  f <- eval(parse(text=func))
  for (i in names(df)){
    y <- f(df[ ,i], na.rm=F)
    new_row <- c(new_row, y)
  }
  df[nrow(df)+ 1, ] <- new_row
  rownames(df)[nrow(df)] <- func
}

df
#>                   x           y
#> 1          1.000000 -2.27557495
#> 2          2.000000 -0.31151886
#> 3          3.000000 -0.87811049
#> 4          4.000000 -1.69935663
#> 5          5.000000  0.76985473
#> 6          6.000000 -0.70577880
#> 7          7.000000  1.46104332
#> 8          8.000000  1.34460671
#> 9          9.000000 -0.51577892
#> 10        10.000000  0.02118427
#> mean       5.500000 -0.27894296
#> median     5.500000 -0.31151886
#> stats::sd  2.738613  1.10605560
#> max       10.000000  1.46104332
#> min        1.000000 -2.27557495

Created on 2021-01-10 by the reprex package (v0.3.0)

Upvotes: 1

Karolis Koncevičius
Karolis Koncevičius

Reputation: 9656

You can store functions in a vector without the quotes:

my_func <- c(mean, median, stats::sd, max, min)

Then it should work. Just note that my_func will turn into a list.

Upvotes: 3

Related Questions