Home > Software engineering >  Write function to repeat calculation for multiple classes in R
Write function to repeat calculation for multiple classes in R

Time:10-03

I'm trying to write my first function in R - very much a beginner! It calculates growth for each weight (wt) class. The number of weight classes is decided based on the number of columns in another data set (but it usually between 1-12, and can be assumed to be 12)

I tried following write a function in R to loop through an equation and use last value for next round in loop but havent been able to apply it in my example.

Here is the starting dataset from which the calc_growth function will be applied to:

performance_param<- data.frame(start_month = c('jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sept', 'oct', 'nov', 'dec'),
                               days_in_month = c(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
                               wt_y_1 = c(0, 60, 105, 150, 178.1, 206.3, 234.4, 262.5,290.6, 318.8, 346.9, 375.0),
                               wt_y_2 = c(403.1, 431.3, 459.4, 487.5, 500.0, 512.5, 525.0, 537.5, 550.0, 562.5, 575.0, 587.5),
                               wt_p_1 = c(600.0, 612.5, 625.0, 637.5, 643.8, 650.0, 656.3, 662.5, 668.8, 675.0, 681.3, 687.5),
                               wt_p_2 = c(693.8, 700, 706.3, 712.5, 715.6, 718.8, 721.9, 725.0, 728.1, 731.3, 734.4, 737.5),
                               wt_p_3 = c(740.6, 743.8, 746.9, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0),
                               wt_p_4 = c(750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0),
                               wt_p_5 = c(750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0),
                               wt_p_6 = c(750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0),
                               wt_p_7 = c(750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0),
                               wt_p_8 = c(750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0),
                               wt_p_9 = c(750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0),
                               wt_p_10 = c(750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0, 750.0))
        

This is the function I've written so far:

calc_growth <- function(wt, days_in_month){
  growth = (wt - lag(wt , default = first(wt )))/days_in_month
return(growth)
}

Thanks for pointing me in the right direction!

CodePudding user response:

Your function looks fine. You can use dplyr::across to apply it on multiple columns:

calc_growth <- function(wt, days_in_month){
  growth = (wt - lag(wt , default = first(wt )))/days_in_month
  return(growth)
}

performance_param %>% 
  mutate(across(starts_with("wt"), ~ calc_growth(.x, days_in_month)))

output

   start_month days_in_month    wt_y_1    wt_y_2    wt_p_1    wt_p_2    wt_p_3 wt_p_4 wt_p_5 wt_p_6 wt_p_7 wt_p_8 wt_p_9 wt_p_10
1          jan            31 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000      0      0      0      0      0      0       0
2          feb            28 2.1428571 1.0071429 0.4464286 0.2214286 0.1142857      0      0      0      0      0      0       0
3          mar            31 1.4516129 0.9064516 0.4032258 0.2032258 0.1000000      0      0      0      0      0      0       0
4          apr            30 1.5000000 0.9366667 0.4166667 0.2066667 0.1033333      0      0      0      0      0      0       0
5          may            31 0.9064516 0.4032258 0.2032258 0.1000000 0.0000000      0      0      0      0      0      0       0
6          jun            30 0.9400000 0.4166667 0.2066667 0.1066667 0.0000000      0      0      0      0      0      0       0
7          jul            31 0.9064516 0.4032258 0.2032258 0.1000000 0.0000000      0      0      0      0      0      0       0
8          aug            31 0.9064516 0.4032258 0.2000000 0.1000000 0.0000000      0      0      0      0      0      0       0
9         sept            30 0.9366667 0.4166667 0.2100000 0.1033333 0.0000000      0      0      0      0      0      0       0
10         oct            31 0.9096774 0.4032258 0.2000000 0.1032258 0.0000000      0      0      0      0      0      0       0
11         nov            30 0.9366667 0.4166667 0.2100000 0.1033333 0.0000000      0      0      0      0      0      0       0
12         dec            31 0.9064516 0.4032258 0.2000000 0.1000000 0.0000000      0      0      0      0      0      0       0

To add (rather than overwrite) columns:

performance_param %>% 
  mutate(across(starts_with("wt"), ~ calc_growth(.x, days_in_month),
                .names = "{col}_new"))
  • Related