Reputation: 13
I'm creating a formula that iterates across all rows within my data frame, this dynamic formula changes by row and is linked to three variables within the first 3 columns.
I may be a bit off in my current approach as I'm fairly new to R, so please let me know if there's another solution I'm missing here when reading below.
I have so far tried lapplying a function that loops through every row and implements the changing formula to each series.
I have replicated my issue below with a smaller scale data set:
The first three columns are the variables that I wish to use within the formula. The first for loop, is to keep these 3 columns values consistent.
For all other observed values (a time series) I want to apply the following formula which takes the current values and then applies a functional form using the values in the referenced column.
The code below works when scale, alpha and beta are static numbers, however when I try referencing them by name I get NAs throughout with no error message in the console.
# Replicating problem using fake data
df <- data.frame(
scale = c(0.1,0.2,0.3),
Alpha = c(100,200,300),
Beta = c(0.45, 0.84, 0.97),
Jan = c(1,2,3),
Feb = c(2,5,4),
Mar =c(5,3,2))
FormulaA <- lapply(df, function(df){
series = numeric(length(df))
# To keep initial values constant
for (i in (1:3)){
series[i] = df[i]}
# For all other time series data
for (i in (4:length(df))){
# Formula Structure below
series[i] = ( ( ( df[i] * df[scale][i] ) * df[Alpha][i]) / (( df[i] * df[scale][i] ) + df[Beta][i] ) )
}
return(series)
})
I have tried a few methods to get this working, but none seem to stick.
The current output when using static numbers and combined with a do.call(rbind.data.frame, FormulaA)
seems to get the format correct, but the numbers are not.
Desired output:
scale Alpha Beta Jan Feb Mar
1 0.1 100 0.5 18.2 30.8 52.6
2 0.2 200 0.8 64.5 108.7 83.3
3 0.3 300 1.0 144.4 165.9 114.6
Any help or guidance would be greatly appreciated, thank you for reading!
Upvotes: 1
Views: 649
Reputation: 887891
We can use mutate_at
to select the columns of interest and then do the calculation for each column
library(dplyr)
df %>%
mutate_at(vars(Jan:Mar), ~ round((. * scale * Alpha)/((. * scale) + Beta), 1))
# scale Alpha Beta Jan Feb Mar
#1 0.1 100 0.45 18.2 30.8 52.6
#2 0.2 200 0.84 64.5 108.7 83.3
#3 0.3 300 0.97 144.4 165.9 114.6
In base R
, we can use lapply
df[4:6] <- lapply(df[4:6], function(x)
round((x * df$scale * df$Alpha)/((x * df$scale) + df$Beta), 1))
Upvotes: 3