If () statement or while () loop in R - r

x=matrix(0)
test <- vector(mode="numeric", length=196)
for(i in 1:196){
x=c[c(1:(200+i*50)),]
ts=BiCopGofTest(x[,1], x[,2], 1, par = 0.6 ,method="white",max.df = 30, B = 0, obj = NULL)
test[i]=ts$statistic}
plot(test, type='l')
I have the matrix c which has 10,000 rows and 2 columns. I took the first 200 rows of matrix c and I calculated the value of the test. Each time I was increasing the number of rows by 50 and I was calculating the test. This is what is written in the code above.
What I want to do now is the following. I want to repeat the same process but when the test is greater than 7.81 I want to stop and return the array x. I want to use the array later so it's important to store it. Should I use an IF statement or a WHILE loop? Any help will be highly appreciated.

Note that by doing
x=c[c(1:(200+i*50)),]
in your loop, you are overwriting x, and you lose the original matrix. Also, your subset statement is not really correct. You should create a new variable which holds the subset of rows in your loop. You might do something like:
x=matrix(runif(10000*2,0,1),10000,2)
test <- vector(mode="numeric", length=196)
i=0
while(max(test)<7.81 & 200+i*50<=nrow(x) )
{
y = x[seq(1,200+i*50),] # y contains the first 200+i*50 rows of x
ts= runif(1,1,7.9) # random test statistic, enter yours here.
test[i]= sum(ts)
i=i+1
}
plot(test, type='l')
This will continue your loop until either:
there are no more rows in x
the test statistic is greater than 7.81
Note that I do not have the package that includes BiCopGofTest, so I just used runif as my test statistic ;)
Hope this helps!

Related

How do you create a function that row reduces a matrix in R?

So far I've tried the following code but it didn't work in R-studio; it just hangs there.
Am I doing something wrong? This is my first real R code project so I'd love suggestions!
new.rref <- function(M,fractions=FALSE)
{
#M is a matrix.
#Require numeric matricies.
if ((!is.matrix(M)) || (!is.numeric(M)))
stop("Sorry pal! Data not a numeric matrix.")
#Specify and differentiate between rows and columns.
r=nrow(M)
c=ncol(M)
#Now establish a continuous loop (*needed help on this one)
#According to the help documents I've read, this has to do with a
#computerized version of the Gaussian Reducing Algorithm
#While 1<r and 1<c, must set first column entries in which
#1:r < 1 equal to zero. This while loop is used to loop the
#algorithm until a specific condition is met -- in this case,
#until elements in the first column to which 1:r < 1
#are set to zero.
while((1<=r) & (1<=c))
new <- M[,1]
new[1:r < y.position] <- 0
# Now here's the fun part :)
#We need to find the maximum leading coefficient that lies
#at or below the current row.
new1 <- which.max(abs(new))
#We will assign these values to the vector "LC"
LC <- col[which]
#Now we need to allow for row exchange!
#Basically tells R that M[c(A,B),] = M[c(B,A),].
if (which > 1) { M[c(1,which),]<-A[c(which,1),] }
#Now we have to allow for the pivot, "sweep", and restoration
#of current row. I totally didn't know how to do this so I
#used and changed some code from different documentations.
#PIVOT (friends reference)
M[1,]<-M[1,]/LC
new2 <-M[1,]
#CLEAN
M <- M - outer(M[,x.position],new2)
#RESTORE
A[1,]<-new2
#Last, but certantly not least, we're going to round the matrix
#off to a certain value. I might have did this wrong.
round(M)
return(M)
print(M)
}
Edit: I added the first line, for some reason it got deleted.
Edit 2: Say you have a matrix M=matrix(c(2,3,4,7), nrow=2, ncol=2, byrow=TRUE); new.rref(M) needs to produce the reduced row echelon form of matrix M. I already did the math; new.rref(M) should be equal to matrix(c(1,0,0,1), nrow=2, ncol=2, byrow=T

Poisson Process algorithm in R (renewal processes perspective)

I have the following MATLAB code and I'm working to translating it to R:
nproc=40
T=3
lambda=4
tarr = zeros(1, nproc);
i = 1;
while (min(tarr(i,:))<= T)
tarr = [tarr; tarr(i, :)-log(rand(1, nproc))/lambda];
i = i+1;
end
tarr2=tarr';
X=min(tarr2);
stairs(X, 0:size(tarr, 1)-1);
It is the Poisson Process from the renewal processes perspective. I've done my best in R but something is wrong in my code:
nproc<-40
T<-3
lambda<-4
i<-1
tarr=array(0,nproc)
lst<-vector('list', 1)
while(min(tarr[i]<=T)){
tarr<-tarr[i]-log((runif(nproc))/lambda)
i=i+1
print(tarr)
}
tarr2=tarr^-1
X=min(tarr2)
plot(X, type="s")
The loop prints an aleatory number of arrays and only the last is saved by tarr after it.
The result has to look like...
Thank you in advance. All interesting and supportive comments will be rewarded.
Adding on to the previous comment, there are a few things which are happening in the matlab script that are not in the R:
[tarr; tarr(i, :)-log(rand(1, nproc))/lambda]; from my understanding, you are adding another row to your matrix and populating it with tarr(i, :)-log(rand(1, nproc))/lambda].
You will need to use a different method as Matlab and R handle this type of thing differently.
One glaring thing that stands out to me, is that you seem to be using R: tarr[i] and M: tarr(i, :) as equals where these are very different, as what I think you are trying to achieve is all the columns in a given row i so in R that would look like tarr[i, ]
Now the use of min is also different as R: min() will return the minimum of the matrix (just one number) and M: min() returns the minimum value of each column. So for this in R you can use the Rfast package Rfast::colMins.
The stairs part is something I am not familiar with much but something like ggplot2::qplot(..., geom = "step") may work.
Now I have tried to create something that works in R but am not sure really what the required output is. But nevertheless, hopefully some of the basics can help you get it done on your side. Below is a quick try to achieve something!
nproc <- 40
T0 <- 3
lambda <- 4
i <- 1
tarr <- matrix(rep(0, nproc), nrow = 1, ncol = nproc)
while(min(tarr[i, ]) <= T0){
# Major alteration, create a temporary row from previous row in tarr
temp <- matrix(tarr[i, ] - log((runif(nproc))/lambda), nrow = 1)
# Join temp row to tarr matrix
tarr <- rbind(tarr, temp)
i = i + 1
}
# I am not sure what was meant by tarr' in the matlab script I took it as inverse of tarr
# which in matlab is tarr.^(-1)??
tarr2 = tarr^(-1)
library(ggplot2)
library(Rfast)
min_for_each_col <- colMins(tarr2, value = TRUE)
qplot(seq_along(min_for_each_col), sort(min_for_each_col), geom="step")
As you can see I have sorted the min_for_each_col so that the plot is actually a stair plot and not some random stepwise plot. I think there is a problem since from the Matlab code 0:size(tarr2, 1)-1 gives the number of rows less 1 but I cant figure out why if grabbing colMins (and there are 40 columns) we would create around 20 steps. But I might be completely misunderstanding! Also I have change T to T0 since in R T exists as TRUE and is not good to overwrite!
Hope this helps!
I downloaded GNU Octave today to actually run the MatLab code. After looking at the code running, I made a few tweeks to the great answer by #Croote
nproc <- 40
T0 <- 3
lambda <- 4
i <- 1
tarr <- matrix(rep(0, nproc), nrow = 1, ncol = nproc)
while(min(tarr[i, ]) <= T0){
temp <- matrix(tarr[i, ] - log(runif(nproc))/lambda, nrow = 1) #fixed paren
tarr <- rbind(tarr, temp)
i = i + 1
}
tarr2 = t(tarr) #takes transpose
library(ggplot2)
library(Rfast)
min_for_each_col <- colMins(tarr2, value = TRUE)
qplot(seq_along(min_for_each_col), sort(min_for_each_col), geom="step")
Edit: Some extra plotting tweeks -- seems to be closer to the original
qplot(seq_along(min_for_each_col), c(1:length(min_for_each_col)), geom="step", ylab="", xlab="")
#or with ggplot2
df1 <- cbind(min_for_each_col, 1:length(min_for_each_col)) %>% as.data.frame
colnames(df1)[2] <- "index"
ggplot() +
geom_step(data = df1, mapping = aes(x = min_for_each_col, y = index), color = "blue") +
labs(x = "", y = "")
I'm not too familiar with renewal processes or matlab so bear with me if I misunderstood the intention of your code. That said, let's break down your R code step by step and see what is happening.
The first 4 lines assign numbers to variables.
The fifth line creates an array with 40 (nproc) zeros.
The sixth line (which doesnt seem to be used later) creates an empty vector with mode 'list'.
The seventh line starts a while loop. I suspect this line is supposed to say while the min value of tarr is less than or equal to T ...
or it's supposed to say while i is less than or equal to T ...
It actually takes the minimum of a single boolean value (tarr[i] <= T). Now this can work because TRUE and FALSE are treated like numbers. Namely:
TRUE == 1 # returns TRUE
FALSE == 0 # returns TRUE
TRUE == 0 # returns FALSE
FALSE == 1 # returns FALSE
However, since the value of tarr[i] depends on a random number (see line 8), this could lead to the same code running differently each time it is executed. This might explain why the code "prints an aleatory number of arrays ".
The eight line seems to overwrite the assignment of tarr with the computation on the right. Thus it takes the single value of tarr[i] and subtracts from it the natural log of runif(proc) divided by 4 (lambda) -- which gives 40 different values. These fourty different values from the last time through the loop are stored in tarr.
If you want to store all fourty values from each time through the loop, I'd suggest storing it in say a matrix or dataframe instead. If that's what you want to do, here's an example of storing it in a matrix:
for(i in 1:nrow(yourMatrix)){
//computations
yourMatrix[i,] <- rowCreatedByComputations
}
See this answer for more info about that. Also, since it's a set number of values per run, you could keep them in a vector and simply append to the vector each loop like this:
vector <- c(vector,newvector)
The ninth line increases i by one.
The tenth line prints tarr.
the eleveth line closes the loop statement.
Then after the loop tarr2 is assigned 1/tarr. Again this will be 40 values from the last time through the loop (line 8)
Then X is assigned the min value of tarr2.
This single value is plotted in the last line.
Also note that runif samples from the uniform distribution -- if you're looking for a Poisson distribution see: Poisson
Hope this helped! Let me know if there's more I can do to help.

How to remove the for loop and perform vectorization for data frame variables?

I have a data frame (V6Stationary42Obs1D.df) with 6 variables. For the 1st variable of my data frame I obtain the value as follows ("1" in effrectpl[i,1] indicates I obtained the value for the 1st variable):
sum <- 0
for (i in as.integer(1:5)) { # 5= no. of variables - 1 = 6-1=5
sum <- sum + conditionalGb(as.matrix(V6Stationary42Obs1D.df[gctemplate(6,1,1)[effrectpl[i,1],]][(1+0):42,]), nx = 1, ny = 1, order = 5)[[2]]
}
sum
For the 2nd variable of my data frame I obtain the value as follows ("2" in effrectpl[i,2] indicates I obtained the value for the 2nd variable):
sum <- 0
for (i in as.integer(1:5)) {
sum <- sum + conditionalGb(as.matrix(V6Stationary42Obs1D.df[gctemplate(6,1,1)[effrectpl[i,2],]][(1+0):42,]), nx = 1, ny = 1, order = 5)[[2]]
} # "6" in gctemplate(6,1,1) is the no. of variables in the data frame
# there is no change other than the one in effrectpl[i,2] for the 2nd variable
sum
There are 6 variables in my data variable, and I have to do the same for each variable (The number of variables will change when I convert this mass to a function; notably, for neuroscience sometimes there may be about 300 variables! and guess the calculation load). I need a vectorized solution that will overcome the above trouble.
What I did (thought):
sum <- c(0,0,0,0,0,0)
for (i in as.integer(1:5)) {
sum??? <- sum + ????
}
sum
Though I know s/t/...apply family, in this particular problem I could not figure out how to handle them as well.
Any help will be greatly appreciated. Thx in advance.
Note: I found the following for-inside-for solution, and now, think that maybe a vectorized solution either difficult or unnecessary in the above case. Anyway, if I see some sort of non-for solution, I will be glad.
for (j in as.integer(1:6)) {
sum[j] <- 0
for (i in as.integer(1:5)) {
sum[j] <- sum[j] + conditionalGb(as.matrix(V6Stationary42Obs1D.df[gctemplate(6,1,1)[effrectpl[i,j],]][(1+0):42,]), nx = 1, ny = 1, order = 5)[[2]]
}
print(sum[j])
}
If computation speed is not your concern and you understand what you are doing then for loop is fine. Its not wrong. It can be made more efficient by vectorization but thats not a necessity.
It is very difficult to provide you with a solution as the example is very hard to follow and calls functions which I have no idea whats its doing, but in general if you have a function f(i) that depends on i you can turn
sum = 0
for( i in 1:n) sum = sum + f(i)
into
sum(sapply(1:n,function(i) f(i)))
BTW its a bad idea to call your variable sum since that is also the name of a common function in R.

Issues with nested while loop in for loop for R

I am using R to code simulations for a research project I am conducting in college. After creating relevant data structures and generating data, I seek to randomly modify a proportion P of observations (in increments of 0.02) in a 20 x 20 matrix by some effect K. In order to randomly determine the observations to be modified, I sample a number of integers equal to P*400 twice to represent row (rRow) and column (rCol) indices. In order to guarantee that no observation will be modified more than once, I perform this algorithm:
I create a matrix, alrdyModded, that is 20 x 20 and initialized to 0s.
I take the first value in rRow and rCol, and check whether alrdyModded[rRow[1]][rCol[1]]==1; WHILE alrdyModded[rRow[1]][rCol[1]]==1, i randomly select new integers for the indices until it ==0
When alrdyModded[rRow[1]][rCol[1]]==0, modify the value in a treatment matrix with same indices and change alrdyModded[rRow[1]][rCol[1]] to 1
Repeat for the entire length of rRow and rCol vectors
I believe a good method to perform this operation is a while loop nested in a for loop. However, when I enter the code below into R, I receive the following error code:
R CODE:
propModded<-1.0
trtSize<-2
numModded<-propModded*400
trt1<- matrix(rnorm(400,0,1),nrow = 20, ncol = 20)
cont<- matrix(rnorm(400,0,1),nrow = 20, ncol = 20)
alrdyModded1<- matrix(0, nrow = 20, ncol = 20)
## data structures for computation have been intitialized and filled
rCol<-sample.int(20,numModded,replace = TRUE)
rRow<-sample.int(20,numModded,replace = TRUE)
## indices for modifying observations have been generated
for(b in 1:numModded){
while(alrdyModded1[rRow[b]][rCol[b]]==1){
rRow[b]<-sample.int(20,1)
rCol[b]<-sample.int(20,1)}
trt1[rRow[b]][rCol[b]]<-'+'(trt1[rRow[b]][rCol[b]],trtSize)
alrdyModded[rRow[b]][rCol[b]]<-1
}
## algorithm for guaranteeing no observation in trt1 is modified more than once
R OUTPUT
" Error in while (alrdyModded1[rRow[b]][rCol[b]] == 1) { :
missing value where TRUE/FALSE needed "
When I take out the for loop and run the code, the while loop evaluates the statement just fine, which implies an issue with accessing the correct values from the rRow and rCol vectors. I would appreciate any help in resolving this problem.
It appears you're not indexing right within the matrix. Instead of having a condition like while(alrdyModded1[rRow[b]][rCol[b]]==1){, it should read like this: while(alrdyModded1[rRow[b], rCol[b]]==1){. Matrices are indexed like this: matrix[1, 1], and it looks like you're forgetting your commas. The for-loop should be something closer to this:
for(b in 1:numModded){
while(alrdyModded1[rRow[b], rCol[b]]==1){
rRow[b]<-sample.int(20,1)
rCol[b]<-sample.int(20,1)}
trt1[rRow[b], rCol[b]]<-'+'(trt1[rRow[b], rCol[b]],trtSize)
alrdyModded1[rRow[b], rCol[b]]<-1
}
On a side note, why not make alrdyModded1 a boolean matrix (populated with just TRUE and FALSE values) with alrdyModded1<- matrix(FALSE, nrow = 20, ncol = 20) in line 7, and have the condition be just while(alrdyModded1[rRow[b], rCol[b]]){ instead?

porting Matlab cells to R to collect output from FOR loop

I have an ODE model in Matlab for which I'm interested in performing some parameter sweeps.
I am trying to port the following code from Matlab to R
for i = 1:numel(sweep1)
initial_conditions(6)=sweep1(i);
for j = 1:numel(sweep2)
parameters(3)=sweep2(j);
[t,y] = ode23s(#(timespan, initial_conditions) MODEL(timespan, initial_conditions, parameters), timespan, initial_conditions);
results_cell{i,j}=[y(end,1),y(end,2)];
The 2 FOR statements above vary first 1 initial condition (i), then for each i vary a parameter (j) and run the solver. The output from the solver for each iteration of the loop is then collected in a cell 'results_cell'
This runs fine in Matlab but I need to port it to R. The loops are the same and the solver code is implemented using deSolve, however I am not sure how to collect the results from the solver at each iteration of the loop as R doesn't have cells like Matlab, and how to gather {i,j} from each loop along with the 2 ode outputs.
Ultimately I would like to plot a heat map of the ode solver output vs the values in each of the 2 parameter sweeps.
Thanks for any help.
Here what I would do: I run the ode23 once to get the structure of the solution.
sweep1 =2
sweep2 =3
library(pracma)
f <- function(t, x,i=1,j=0)
as.matrix(c(x[1] * ((i+j) - x[2]^2) -x[2], x[1]))
t0 <- 0
tf <- 20
x0 <- as.matrix(c(0, 0.25))
sol = ode23(f, t0, tf, x0,1,1)$y
res = tail(sol,1)
Then I use replicate to create the structure of the final output matrix. Using this trick avoid us to deal with pre-allocating arrays. replicate will do for us.
results_cell = replicate(sweep1,replicate(sweep2,res))
I just run my final simulation and assign each solution to results_cell
for (i in seq(sweep1))
for (j in seq(sweep2))
results_cell[,,j,i] = tail(ode23(f, t0, tf, x0,i,j)$y,1)
I'm assuming sweep1 and sweep2 are both vectors of numbers. What you can do is use expand.grid to make a data frame of the combinations of that, and then loop over the frame once with apply:
# sweep 1, sweep 2
sweep1 <- c(1, 2, 4)
sweep2 <- c(3, 5, 7)
# expand out the combinations
combinations <- expand.grid(sweep1=sweep1, sweep2=sweep2)
# apply over the data frame
results <- apply(combinations, 1, function(row) {
# set up the parameters from the row which has been passed in.
initial_conditions[6] <- row["sweep1"]
parameters[3] <- row["sweep2"]
# call ode23s
res <- ode23s(initial_conditons, parameters, function, whatever, ...)
# there should be a nicer way than calling nrow twice here, but R doesn't
# seem to have the nice 'end' keyword
# also, we copy in the row, so that's in the output.
c(row, one=res[nrow(res), 1], two=res[nrow(res), 2])
})
# because the apply has flipped rows to columns...
results <- as.data.frame(t(results))
results
# sweep1 sweep2 one two
# 1 1 3 ... ...
# 2 2 3 ... ...
# ...
The result of all this is a data frame of the input combinations and the output combinations. If you want more factors, add on a sweep3, but beware of the combinatorial complexity...

Resources