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"))