data length cannot be over width of moving average - r

I use quantmod, to calculate the moving average over 2000 dataframes with loop
price = xts object
price <- cbind(price, SMA(price, 5), SMA(price, 10),
SMA(price, 20), SMA(price, 60), SMA(price, 120),
SMA(price, 180), SMA(price, 240))
But some data don't exceed the number of width, stop running in the middle. In that case, I just want to fill NA only.
I need some support to solve this problem.
Or if I need to use any other package for solving this problem, let me know
Thanks

Moving average functions give an error when the chosen period is longer than the available data. As #RuiBarradas mentions in the comment, for a SMA zoo::rollmean could work. As you need to loop over quite a few data.frames a function is easier. The function below could be used in an lapply function or just in a loop.
I created a sub function inside the bigger function to check if the chosen period is bigger than the rows supplied. If so, return a vector of NA's else return a SMA. After that, loop over the periods to return a data.frame with the supplied price column and all the SMA columns with a name so you can see which SMA is in which column.
Note that there is no error handling in case of incorrect inputs. Sample data below.
# periods for the SMA
periods <- c(5, 10, 20, 60, 120, 180, 240)
get_smas <- function(price, n) {
my_sma <- function(x, n = 10) {
if (n < 1 || n > NROW(x)) {
out <- rep(NA_real_, NROW(x))
} else {
# change SMA for EMA if you want the EMA's
out <- TTR::SMA(x, n = n)
}
out
}
# combine the price column with the ma's. Reduce works backwards, so price column last
price_combined <- Reduce(cbind, lapply(n, function(x) my_sma(price, n = x)), price)
# turn matrix into data.frame
price_combined <- data.frame(price_combined)
# rename columns, assuming price column has a column name.
# change paste0 value from SMA to EMA if EMA is used.
names(price_combined) <- c(names(price_combined)[1], paste0("SMA_", n))
price_combined
}
# supply a price and a vector of periods
my_prices <- get_smas(price, periods)
head(my_prices, 2)
Close SMA_5 SMA_10 SMA_20 SMA_60 SMA_120 SMA_180 SMA_240
1 182.01 NA NA NA NA NA NA NA
2 179.70 NA NA NA NA NA NA NA
tail(my_prices, 2)
Close SMA_5 SMA_10 SMA_20 SMA_60 SMA_120 SMA_180 SMA_240
142 156.79 154.156 152.053 147.475 145.4393 156.1770 NA NA
143 157.35 154.556 152.941 148.381 145.4292 156.0474 NA NA
data:
# close prices of aapl from 2022-01-03 to 2022-07-28
price <- structure(list(Close = c(182.009995, 179.699997, 174.919998,
172, 172.169998, 172.190002, 175.080002, 175.529999, 172.190002,
173.070007, 169.800003, 166.229996, 164.509995, 162.410004, 161.619995,
159.779999, 159.690002, 159.220001, 170.330002, 174.779999, 174.610001,
175.839996, 172.899994, 172.389999, 171.660004, 174.830002, 176.279999,
172.119995, 168.639999, 168.880005, 172.789993, 172.550003, 168.880005,
167.300003, 164.320007, 160.070007, 162.740005, 164.850006, 165.119995,
163.199997, 166.559998, 166.229996, 163.169998, 159.300003, 157.440002,
162.949997, 158.520004, 154.729996, 150.619995, 155.089996, 159.589996,
160.619995, 163.979996, 165.380005, 168.820007, 170.210007, 174.070007,
174.720001, 175.600006, 178.960007, 177.770004, 174.610001, 174.309998,
178.440002, 175.059998, 171.830002, 172.139999, 170.089996, 165.75,
167.660004, 170.399994, 165.289993, 165.070007, 167.399994, 167.229996,
166.419998, 161.789993, 162.880005, 156.800003, 156.570007, 163.639999,
157.649994, 157.960007, 159.479996, 166.020004, 156.770004, 157.279999,
152.059998, 154.509995, 146.5, 142.559998, 147.110001, 145.539993,
149.240005, 140.820007, 137.350006, 137.589996, 143.110001, 140.360001,
140.520004, 143.779999, 149.639999, 148.839996, 148.710007, 151.210007,
145.380005, 146.139999, 148.710007, 147.960007, 142.639999, 137.130005,
131.880005, 132.759995, 135.429993, 130.059998, 131.559998, 135.869995,
135.350006, 138.270004, 141.660004, 141.660004, 137.440002, 139.229996,
136.720001, 138.929993, 141.559998, 142.919998, 146.350006, 147.039993,
144.869995, 145.860001, 145.490005, 148.470001, 150.169998, 147.070007,
151, 153.039993, 155.350006, 154.089996, 152.949997, 151.600006,
156.789993, 157.350006)), class = "data.frame", row.names = c(NA,
-143L))

rollmeanr and rollapplyr can handle the situation with fewer data items than width.
library(zoo)
price <- 1:6
rollmeanr(price, 10, fill = NA)
## [1] NA NA NA NA NA NA
w <- c(5, 10, 20, 60, 120, 180, 240)
sapply(setNames(w, w), rollmeanr, x = price, fill = NA)
## 5 10 20 60 120 180 240
## [1,] NA NA NA NA NA NA NA
## [2,] NA NA NA NA NA NA NA
## [3,] NA NA NA NA NA NA NA
## [4,] NA NA NA NA NA NA NA
## [5,] 3 NA NA NA NA NA NA
## [6,] 4 NA NA NA NA NA NA

Related

tsCV h-step-ahead when h>1

schematic 4-step-ahead forecasts
According to the illustration above, I'd expect the time period of the first CV error (first non-NA values) in the column h=4 to be period 10, right? The result below shows that all first CV errors start at period 7. Why is this so?
> data <- ts(rnorm(n = 50, mean = 10, sd = 5))
> tsCV(data, forecastfunction = splinef, h = 4, initial = 6) %>% head(12)
Time Series:
Start = 1
End = 12
Frequency = 1
h=1 h=2 h=3 h=4
1 NA NA NA NA
2 NA NA NA NA
3 NA NA NA NA
4 NA NA NA NA
5 NA NA NA NA
6 NA NA NA NA
7 -0.6898367 1.94707898 -0.4241705 2.6114473
8 2.2835535 -0.03213156 3.0590506 2.9266469
9 -1.0397064 1.90081726 1.6177550 4.7870414
10 2.3104741 2.08295460 5.3077838 5.1881762
11 1.2481952 4.36896765 4.1453033 3.9093216
12 3.9553215 3.68404796 3.4004571 0.4572387
Image source: https://otexts.com/fpp2/accuracy.html, Rob J Hyndman
From the help file for forecast::tsCV:
Value
Numerical time series object containing the forecast errors as a vector (if h=1) and a matrix otherwise. The time index corresponds to the last period of the training data. The columns correspond to the forecast horizons.
So the cell at time=7 and h=4 gives forecasts for time 11.

Create column from data on dynamic number of columns depending on availabity in R

Given a uncertain number of columns containing source values for the same variable I would like to create a column that defines the final value to be selected depending on source importance and availability.
Reproducible data:
set.seed(123)
actuals = runif(10, 500, 1000)
get_rand_vector <- function(){return (runif(10, 0.95, 1.05))}
get_na_rand_ixs <- function(){return (round(runif(5,0,10),0))}
df = data.frame("source_1" = actuals*get_rand_vector(),
"source_2" = actuals*get_rand_vector(),
"source_n" = actuals*get_rand_vector())
df[["source_1"]][get_na_rand_ixs()] <- NA
df[["source_2"]][get_na_rand_ixs()] <- NA
df[["source_n"]][get_na_rand_ixs()] <- NA
My manual solution is as follows:
df$available <- ifelse(
!is.na(df$source_1),
df$source_1,
ifelse(
!is.na(df$source_2),
df$source_2,
df$source_n
)
)
Given the desired result of:
source_1 source_2 source_n available
1 NA NA NA NA
2 NA NA 930.1242 930.1242
3 716.9981 NA 717.9234 716.9981
4 NA 988.0446 NA 988.0446
5 931.7081 NA 924.1101 931.7081
6 543.6802 533.6798 NA 543.6802
7 744.6525 767.4196 783.8004 744.6525
8 902.8788 955.1173 NA 902.8788
9 762.3690 NA 761.6135 762.3690
10 761.4092 702.6064 708.7615 761.4092
How could I automatically iterate over the available sources to set the data to be considered? Given in some cases n_sources could be 1,2,3..,7 and priority follows the natural order (1 > 2 >..)
Once you have all of the candidate vectors in order and in an appropriate data structure (e.g., data.frame or matrix), you can use apply to apply a function over the rows. In this case, we just look for the first non-NA value. Thus, after the first block of code above, you only need the following line:
df$available <- apply(df, 1, FUN = function(x) x[which(!is.na(x))[1]])
coalesce() from dplyr is designed for this:
library(dplyr)
df %>%
mutate(available = coalesce(!!!.))
source_1 source_2 source_n available
1 NA NA NA NA
2 NA NA 930.1242 930.1242
3 716.9981 NA 717.9234 716.9981
4 NA 988.0446 NA 988.0446
5 931.7081 NA 924.1101 931.7081
6 543.6802 533.6798 NA 543.6802
7 744.6525 767.4196 783.8004 744.6525
8 902.8788 955.1173 NA 902.8788
9 762.3690 NA 761.6135 762.3690
10 761.4092 702.6064 708.7615 761.4092

Fill data frame by column with for loop

I created an empty data frame with 11 columns and 15 rows and subsequently named the columns.
L_df <- data.frame(matrix(ncol = 11, nrow = 15))
names(L_df) <- paste0("L_por", 0:10)
w <- c(0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2, 2.2, 2.4, 2.6, 2.8, 3)
wu <- 0
L <- 333.7
pm <- c(2600, 2574, 2548, 2522, 2496, 2470, 2444, 2418, 2392, 2366, 2340)
The data frame looks like this:
head(L_df)
L_por0 L_por1 L_por2 L_por3 L_por4 L_por5 L_por6 L_por7 L_por8 L_por9 L_por10
1 NA NA NA NA NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA NA NA NA NA
4 NA NA NA NA NA NA NA NA NA NA NA
5 NA NA NA NA NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA NA NA NA NA
Now, I would like to fill the data frame by column, based on a formula. I tried to express this with a nested for loop:
for (i in 1:ncol(L_df)) {
pm_tmp <- pm[i]
col_tmp <- colnames(L_df)[i]
for (j in 1:nrow(L_df)) {
w_tmp <- w[j]
L_por_tmp <- pm_tmp*L*((w_tmp-wu)/100)
col_tmp[j] <- L_por_tmp
}
}
For each column, I iterate over a predefined vector pm of length 11. For each row, I iterate over a predefined vector w of length 15 (repeats each column).
Example: First, select pm[1] for the first column. Second, select w[i] for each row in the first column. Store the formula in L_por_tmp and use it to fill the first column from row1 to row15. The whole procedure should start all over again for the second column (with pm[2]) with w[i] for each row and so on. wu and L are fixed in the formula.
R executes the code without an error. When I check the tmp values, they are correct. However, the data frame remains empty. L_df does not get filled. I would like solve this with a loop but if you have other solutions, I am happy to hear them! I get the impression there might be a smoother way of doing this. Cheers!
Solution
L_df <- data.frame(sapply(pm, function(x) x * L * ((w - wu) / 100)))
names(L_df) <- c("L_por0", "L_por1", "L_por2", "L_por3", "L_por4", "L_por5",
"L_por6", "L_por7", "L_por8", "L_por9", "L_por10")
L_df
L_por0 L_por1 L_por2 L_por3 L_por4 L_por5 L_por6 L_por7
1 1735.24 1717.888 1700.535 1683.183 1665.830 1648.478 1631.126 1613.773
2 3470.48 3435.775 3401.070 3366.366 3331.661 3296.956 3262.251 3227.546
3 5205.72 5153.663 5101.606 5049.548 4997.491 4945.434 4893.377 4841.320
4 6940.96 6871.550 6802.141 6732.731 6663.322 6593.912 6524.502 6455.093
5 8676.20 8589.438 8502.676 8415.914 8329.152 8242.390 8155.628 8068.866
6 10411.44 10307.326 10203.211 10099.097 9994.982 9890.868 9786.754 9682.639
7 12146.68 12025.213 11903.746 11782.280 11660.813 11539.346 11417.879 11296.412
8 13881.92 13743.101 13604.282 13465.462 13326.643 13187.824 13049.005 12910.186
9 15617.16 15460.988 15304.817 15148.645 14992.474 14836.302 14680.130 14523.959
10 17352.40 17178.876 17005.352 16831.828 16658.304 16484.780 16311.256 16137.732
11 19087.64 18896.764 18705.887 18515.011 18324.134 18133.258 17942.382 17751.505
12 20822.88 20614.651 20406.422 20198.194 19989.965 19781.736 19573.507 19365.278
13 22558.12 22332.539 22106.958 21881.376 21655.795 21430.214 21204.633 20979.052
14 24293.36 24050.426 23807.493 23564.559 23321.626 23078.692 22835.758 22592.825
15 26028.60 25768.314 25508.028 25247.742 24987.456 24727.170 24466.884 24206.598
L_por8 L_por9 L_por10
1 1596.421 1579.068 1561.716
2 3192.842 3158.137 3123.432
3 4789.262 4737.205 4685.148
4 6385.683 6316.274 6246.864
5 7982.104 7895.342 7808.580
6 9578.525 9474.410 9370.296
7 11174.946 11053.479 10932.012
8 12771.366 12632.547 12493.728
9 14367.787 14211.616 14055.444
10 15964.208 15790.684 15617.160
11 17560.629 17369.752 17178.876
12 19157.050 18948.821 18740.592
13 20753.470 20527.889 20302.308
14 22349.891 22106.958 21864.024
15 23946.312 23686.026 23425.740
Explanation
The sapply() function can be used to iterate over vectors in a more idiomatic way for R programming. We iterate over pm and use your formula once since R is vectorised; each time it creates a vector of length 15 (so 11 vectors of length 15), and when we wrap it in data.frame() returns the data frame you want and we add in the column names.
NOTE: Applying functions to every element of a vector using an apply() family function has some different implications than iterating using for loops. In your case, I think sapply() is easier and more understandable. For more information on when you need a loop or when something like apply is better, see for example this discussion from Hadley Wickham's Advanced R book.
You are just doing a small mistake and you were almost there, Edited your function:
for (i in 1:ncol(L_df)) {
pm_tmp <- pm[i]
col_tmp <- colnames(L_df)[i]
for (j in 1:nrow(L_df)) {
w_tmp <- w[j]
L_por_tmp <- pm_tmp*L*((w_tmp-wu)/100)
L_df[ j ,col_tmp] <- L_por_tmp ##You must have used df[i, j] referencing here
}
}
Output:
Just printing the head of few rows:
L_df
L_por0 L_por1 L_por2 L_por3 L_por4 L_por5 L_por6 L_por7 L_por8 L_por9 L_por10
1 1735.24 1717.888 1700.535 1683.183 1665.830 1648.478 1631.126 1613.773 1596.421 1579.068 1561.716
2 3470.48 3435.775 3401.070 3366.366 3331.661 3296.956 3262.251 3227.546 3192.842 3158.137 3123.432
3 5205.72 5153.663 5101.606 5049.548 4997.491 4945.434 4893.377 4841.320 4789.262 4737.205 4685.148

How to skip an error in loop while preserving the missing element as a blank column?

I have the following chunk of data:
> dput(data)
structure(c(0.640372781, 0.54596394, 0.364612178, 0.554321638,
0.623891566, 0.299900389, 0.629781465, 0.502673674, 0.414942748,
0.485381455, 0.629032253, 0.201974626, 0.549820206, 0.49277897,
0.299640651, 0.443151949, 0.506297992, 0.259198111, 0.635090505,
0.597640686, 0.430193856, 0.631067648, 0.662995875, 0.391062922,
0.632248042, 0.627503454, 0.432827825, 0.418849204, 0.612201188,
0.227470395, 0.556520484, 0.6095603, 0.414923451, 0.57634896,
0.543780581, 0.320027087, 0.655818488, 0.648937123, 0.497094053,
0.429772696, 0.632386262, 0.270060224, 0.564427852, 0.456642259,
0.492407708, 0.436349654, 0.616355794, 0.248897538, 0.642866477,
0.555022037, 0.358901689, 0.53184597, 0.606299729, 0.342449093,
0.667681177, 0.506448197, 0.370292817, 0.555462276, 0.642302168,
0.42487856, 0.649249462, 0.544035494, 0.394793334, 0.383522657,
0.557789563, 0.220189788, 0.636151283, 0.547825201, 0.391789202,
0.653913292, 0.649412792, 0.452257495, 0.648866884, 0.535907987,
0.392093314, 0.724788138, 0.674157973, 0.494385979, 0.673032345,
0.450686601, 0.369089571, 0.397124065, 0.502592807, 0.197922003
), class = c("xts", "zoo"), .indexCLASS = "Date", tclass = "Date", .indexTZ = "UTC", tzone = "UTC", index = structure(c(1025049600,
1025136000, 1025222400, 1025481600, 1025568000, 1025654400), tzone = "UTC", tclass = "Date"), .Dim = c(6L,
14L), .Dimnames = list(NULL, c("AN8068571086", "BMG3223R1088",
"BMG4388N1065", "BMG6359F1032", "BMG7496G1033", "BMG812761002",
"CA88157K1012", "CH0044328745", "CH0048265513", "GB00B4VLR192",
"GB00B5BT0K07", "GB00B6SLMV12", "GB00BFG3KF26", "GB00BVVBC028"
)))
And this code:
######## INPUTS ######
a <- 0.5
b <- 0.6
results <- list() # list containing loop results
#######################
for (i in 1:nrow(data)) {
input <- as.matrix(data[i,])
#extract column names with a value between a and b
stocks <- matrix(colnames(data[,which(input > a & input < b)]))
# make a vector with new name for the output
date <- head(rownames(input), n=1)
#rename column
colnames(stocks) <- date
#export to list under "date" name
results[[date]] <- stocks
}
If you run it exactly as it is you will get this error:
Error in matrix(colnames(data[, which(input > a & input < b)])) :
'data' must be of a vector type, was 'NULL'
In addition: Warning messages:
1: In min(j, na.rm = TRUE) :
no non-missing arguments to min; returning Inf
2: In max(j, na.rm = TRUE) :
no non-missing arguments to max; returning -Inf
This comes from the third row in data which contains no values between 0.5 and 0.6
matrix(colnames(data[,which(input > a & input < b)]))
After running the above code i run this, which merges all my data together and prepares it for other calculations:
# merge all results in a list
max_length <- max(sapply(results ,length))
final_results <- sapply(results, function(x){
c(x, rep(NA, max_length - length(x)))
})
i need a way to skip that error while still preserving the date name as a blank column in final_results. I am thinking maybe an if function such that if there are no values that lie between a and b an empty matrix of (1x1) is created with the colname = date which should be stored in results list.
another option would be using tryCatch but that will omit the date entirely and between the thousands that i have here it will be impossible to find missing columns.
If you use the tryCatch function that processes your error by returning a matrix with NA value you would get a column with the appropriate date as a name that only contains NA in your final_results. However this would process all errors in the same way so may not be the best solution if your data could throw up different errors.
stocks <- tryCatch(matrix(colnames(data[,which(input > a & input < b)])),
error = function(e) matrix(NA))
A quick solution to your task:
DF <- as.data.frame(data)
DF <- apply(DF, 1, function(x) {
ifelse(x > a & x < b, x, NA_real_)
})
Result of this is:
> DF
2002-06-26 2002-06-27 2002-06-28 2002-07-01 2002-07-02 2002-07-03
AN8068571086 NA 0.5459639 NA 0.5543216 NA NA
BMG3223R1088 NA 0.5026737 NA NA NA NA
BMG4388N1065 0.5498202 NA NA NA 0.5062980 NA
BMG6359F1032 NA 0.5976407 NA NA NA NA
BMG7496G1033 NA NA NA NA NA NA
BMG812761002 0.5565205 NA NA 0.5763490 0.5437806 NA
CA88157K1012 NA NA NA NA NA NA
CH0044328745 0.5644279 NA NA NA NA NA
CH0048265513 NA 0.5550220 NA 0.5318460 NA NA
GB00B4VLR192 NA 0.5064482 NA 0.5554623 NA NA
GB00B5BT0K07 NA 0.5440355 NA NA 0.5577896 NA
GB00B6SLMV12 NA 0.5478252 NA NA NA NA
GB00BFG3KF26 NA 0.5359080 NA NA NA NA
GB00BVVBC028 NA NA NA NA 0.5025928 NA
If you want to drop the columns that are all NAs then you can filter them like this:
DF <- DF[
, apply(DF, 2, function(x) {
sum(is.na(x)) != length(x)
})]
Result after the filtering is:
> DF
2002-06-26 2002-06-27 2002-07-01 2002-07-02
AN8068571086 NA 0.5459639 0.5543216 NA
BMG3223R1088 NA 0.5026737 NA NA
BMG4388N1065 0.5498202 NA NA 0.5062980
BMG6359F1032 NA 0.5976407 NA NA
BMG7496G1033 NA NA NA NA
BMG812761002 0.5565205 NA 0.5763490 0.5437806
CA88157K1012 NA NA NA NA
CH0044328745 0.5644279 NA NA NA
CH0048265513 NA 0.5550220 0.5318460 NA
GB00B4VLR192 NA 0.5064482 0.5554623 NA
GB00B5BT0K07 NA 0.5440355 NA 0.5577896
GB00B6SLMV12 NA 0.5478252 NA NA
GB00BFG3KF26 NA 0.5359080 NA NA
GB00BVVBC028 NA NA NA 0.5025928

Stop a looping function when one value is greater than another within loop

I have been trying to write a while command to stop the looping function when one value generated by the loop exceeds the other. However, I have failed to figure out the proper way to do it.
The for loop runs for 30 days, but I want it to stop as soon as the last value of parasite_l.A is less than than parasite_l.B.
I have included the working code I have for generating the data and the for loop.
Alternative solutions without a limit on the loop would also be greatly appreciated.
# Subject A, initially 400 parasites, growing by 10 %
subA = 400
infA = 1.1
# Subject B, initially 120 parasites, growing by 20 %
subB = 120
infB = 1.2
# How many days to model
days = 30
days_seq = seq(1, days, 1)
# Parasite load for A
parasite_l.A = rep(NA, days)
parasite_l.A[1] = subA
# Parasite load for B
parasite_l.B = rep(NA, days)
parasite_l.B[1] = subB
# Loop for subject A and B
for(i in 1:(days)){
parasite_l.A[i+1] = parasite_l.A[i]*(infA)
parasite_l.B[i+1] = parasite_l.B[i]*(infB)
}
parasite_l.A
parasite_l.B
There is a built-in control flow function for what you are referring to named while. As long as the conditions are met it will continue to loop.
i <- 1
while (parasite_l.A[i] > parasite_l.B[i]) {
parasite_l.A[i+1] = parasite_l.A[i]*(infA)
parasite_l.B[i+1] = parasite_l.B[i]*(infB)
i <- i + 1
}
# parasite_l.A
# [1] 400.0000 440.0000 484.0000 532.4000 585.6400 644.2040 708.6244
# [8] 779.4868 857.4355 943.1791 1037.4970 1141.2467 1255.3714 1380.9085
# [15] 1518.9993 NA NA NA NA NA NA
# [22] NA NA NA NA NA NA NA
# [29] NA NA
# parasite_l.B
# [1] 120.0000 144.0000 172.8000 207.3600 248.8320 298.5984 358.3181
# [8] 429.9817 515.9780 619.1736 743.0084 891.6100 1069.9321 1283.9185
# [15] 1540.7022 NA NA NA NA NA NA
# [22] NA NA NA NA NA NA NA
# [29] NA NA
Use an index value (i), a couple of counters (A.index.value, B.index.value), and a while loop:
# Subject A, initially 400 parasites, growing by 10 %
subA <- A.index.value <- 400
infA <- 1.1
# Subject B, initially 120 parasites, growing by 20 %
subB <- B.index.value <- 120
infB <- 1.2
# How many days to model
days <- 30
days_seq <- seq(1, days, 1)
# Parasite load for A
parasite_l.A <- rep(NA, days)
parasite_l.A[1] <- subA
# Parasite load for B
parasite_l.B <- rep(NA, days)
parasite_l.B[1] <- subB
# While Loop for subject A and B
i <- 1
while (A.index.value > B.index.value) {
parasite_l.A[i+1] <- A.index.value <- parasite_l.A[i]*(infA)
parasite_l.B[i+1] <- B.index.value <- parasite_l.B[i]*(infB)
i <- i + 1
}
parasite_l.A
parasite_l.B
With the results being:
> parasite_l.A
[1] 400.00 440.00 484.00 532.40 585.64 644.20 708.62 779.49 857.44 943.18 1037.50
[12] 1141.25 1255.37 1380.91 1519.00 NA NA NA NA NA NA NA
[23] NA NA NA NA NA NA NA NA
> parasite_l.B
[1] 120.00 144.00 172.80 207.36 248.83 298.60 358.32 429.98 515.98 619.17 743.01
[12] 891.61 1069.93 1283.92 1540.70 NA NA NA NA NA NA NA
[23] NA NA NA NA NA NA NA NA
>
if (parasite_l.A < parasite_l.B) { // if parasite a is less than b, do the following //
for(i in 1:(days)){
parasite_l.A[i+1] = parasite_l.A[i]*(infA)
parasite_l.B[i+1] = parasite_l.B[i]*(infB)
}
}
Use inside the loop something like:
if (parasite_l.A > parasite_l.B) {
break
}

Resources