I'm trying to generate rows of sequences, within a function, for each row in my dataset. The problem I'm running into is that the seq
function errors out because I have multiple rows. I've included an example dataset and my code (sequence call is third from bottom of my function).
df<-data.frame(
'Acct'=c("A","B","A"),
'Rate'=c(8,8,12),
'Amount'=c(1000,1000,1500),
'Freq'=c(2,2,2),
'MtM'=c(6,6,12),
'YtM2'=c(.10,.10,.05),
'periods'=c(12,12,24),
'Price'=c(911.54,911.54,1050.37),
'Date'=c('Sep 2021','Sep 2021', 'May 2021')
)
dur <- function(Rate, periods,YtM2, Price ,MtM,Amount) {
i <- 1:periods
cf <- c(rep(Rate, periods - 1), Amount Rate)
pv <- (cf / (1 YtM2) ^ i)
weight<-pv/Price
seqi<-seq(MtM/periods,MtM,length.out=periods)
endResults<-sum(seqi*weight)
return(seqi)
}
dur(df$Rate,df$periods,df$YtM2,df$Price,df$MtM,df$Amount)
When I run the code I get an error:
Error in seq.default(MtM/periods, MtM, length.out = periods) :
'from' must be of length 1
Ideally, I would just store these sequences temporarily. I'm trying to experiment by using dplyr::group_by
statement where I group by Acct
and Date
and then generate the sequence ie seqi<-df%>%group_by(Acct,Date)%>%seq(MtM/df$periods,df$MtM, length.out=df$periods)
but I just get this error
Error in seq.default(., MtM/df$periods, df$MtM, length.out = df$periods) : 'from' must be of length 1 In addition: Warning message: In seq.default(., MtM/df$periods, df$MtM, length.out = df$periods) : first element used of 'length.out' argument
CodePudding user response:
If you want to apply dur
function for each row, you can use any of the apply function.
For example, with Map
.
with(df, Map(dur, Rate, periods,YtM2, Price ,MtM,Amount))
#[[1]]
# [1] 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0
#[[2]]
# [1] 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0
#[[3]]
# [1] 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5
#[14] 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0
I removed the last Price
argument from the function since it was repeated twice.
CodePudding user response:
We may use do.call
with Map
after subsetting the columns with the order of the input arguments in 'dur'
do.call(Map, c(f = dur, unname(df[c(2, 7, 6, 8, 5, 3)])))
[[1]]
[1] 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0
[[2]]
[1] 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0
[[3]]
[1] 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0