I am having an issue with creating a splice for a weighted index. I have the following sample data:
a=(1:10)
b=(14:23)
c=rep(1,10)
wa=c(2,2,2,2,2,6,6,6,6,6)
wb=c(5,5,5,5,5,2,2,2,2,2)
wc=c(3,3,3,3,3,2,2,2,2,2)
z=data.frame(a,b,c,wa,wb,wc)
z$ind=rowSums(z[,1:3]*z[,4:6])/rowSums(z[,4:6])
Which returns the following data frame:
a b c wa wb wc ind
1 1 14 1 2 5 3 7.5
2 2 15 1 2 5 3 8.2
3 3 16 1 2 5 3 8.9
4 4 17 1 2 5 3 9.6
5 5 18 1 2 5 3 10.3
6 6 19 1 6 2 2 7.6
7 7 20 1 6 2 2 8.4
8 8 21 1 6 2 2 9.2
9 9 22 1 6 2 2 10.0
10 10 23 1 6 2 2 10.8
The weights (wa,wb,wc) have changed at record six. So I would like to splice the index at record six so that 7.6 becomes 11. I need to calculate the values (a,b,c) with the previous record’s weights and divide that by 7.6. Then apply that to all following numbers until the weights change again. The following function allows me to find where one of my weights has changed:
changeWeight=function(x){
for(i in 2:NROW(z)) {
z$test[i] <- if(z$wa[i]-z$wa[i-1]==0) 0 else 1
}
z
}
It will return a value of one wherever the weight has changed like so:
a b c wa wb wc ind test
1 1 14 1 2 5 3 7.5 NA
2 2 15 1 2 5 3 8.2 0
3 3 16 1 2 5 3 8.9 0
4 4 17 1 2 5 3 9.6 0
5 5 18 1 2 5 3 10.3 0
6 6 19 1 6 2 2 7.6 1
7 7 20 1 6 2 2 8.4 0
8 8 21 1 6 2 2 9.2 0
9 9 22 1 6 2 2 10.0 0
10 10 23 1 6 2 2 10.8 0
Now I try to create the value I will multiply by in order to splice the index at record six. I tried the following:
spliceValue=function(x){
for(i in 2:NROW(z)){
z$splice[i]=if(z$test[i]==1&z$splice[i-1]!=NA) (rowSums(z[i,1:3]*z[i-1,4:6])/rowSums(z[i-1,4:6]))/z$ind[i] else z$splice[i-1]
}
z
}
But that returns this error:
Error in if (z$test[i] == 1 & z$splice[i - 1] != NA) z$ind[i - 1]/z$ind[i] else z$splice[i - :
argument is of length zero
What I would like to get is this:
a b c wa wb wc ind test splice
1 1 14 1 2 5 3 7.5 NA NA
2 2 15 1 2 5 3 8.2 0 0.000000
3 3 16 1 2 5 3 8.9 0 0.000000
4 4 17 1 2 5 3 9.6 0 0.000000
5 5 18 1 2 5 3 10.3 0 0.000000
6 6 19 1 6 2 2 7.6 1 1.447638
7 7 20 1 6 2 2 8.4 0 1.447638
8 8 21 1 6 2 2 9.2 0 1.447638
9 9 22 1 6 2 2 10.0 0 1.447638
10 10 23 1 6 2 2 10.8 0 1.447638
Then I can multiply ind by splice and have a nice smooth index.
Expanding the example to have more than one change in weights:
Here, I have changed the functions
changeWeight()andspliceValue()to return vectors that can be added to the data. This does what you want for the expanded example and avoids the environment issues that might occur with the original functions.The condition
z$splice[i - 1]!=NAseemed superfluous. If it’s not, you should consider!is.na(z$splice[i - 1])instead.And, as per the original example, to set the first value of
z$spliceto NA,As a note, this approach may take a while if
zhas many rows.