For statement nested in while statement not working - r

I am learning how to use while and for loops, and am having difficulty executing a for loop within a while loop. I am trying to recurse a simple procedure over a vector, and have the while loop set the conditionals for which parts of the vector are operated upon. This is really just meant as an exercise to understand how to use for and while loops in conjunction.
data <- c(1:200)
n=0
while(n < 100){
for(x in data){
n=x+1
if(x >= 10 & x < 100){
print("double digit")
} else {
print("single digit")
}}}
I want to stop the while loop when the procedure hits x=100 of the vector that runs from 1:200. But instead, the for loop runs through every element within the vector, from 1:200, failing to stop executing when n hits 100.
Would appreciate any advice to help out a new coder, thanks.
I have also tried
for(x in data){
n=x+1
while(n < 100){
if(x >= 10 & x < 100){
print("double digit")
} else {
print("single digit")
}}}
But the code does not stop executing.

First let's try a for loop. Each time through it n will be set to the loop counter plus 1. If this result is between 10 and 100, print a message, if not print something else. Note that no loop depends on n .
data <- c(1:200)
n = 0
for (x in data) {
n = x + 1
if (n < 100) {
if (x >= 10 && x < 100) {
print("double digit")
} else {
print("single digit")
}
}
}
x
#[1] 200
n
#[1] 201
Now for a while loop. I believe it is much simpler, it only envolves one variable, n.
n <- 0
while (n < 100) {
n = n + 1
if (n < 100) {
if (n >= 10) {
print("double digit")
} else {
print("single digit")
}
}
}
n
#[1] 100

Related

How to restart iteration in R loop?

I made a loop to generate a Markov Chain. If the proposal does not satisfy a condition, I want to restart the iteration with a new proposal? Is there a way to do this? My current code is shown below for reference. Currently, it sets the current chain's value to the previous one. But I don't want that. I want it to just restart the "i". So if i=2, and the condition in line 4 is not satisfied, I then want it to stay at i=2 until it is satisfied. Thanks in advance.
ABC_MCMC<-function(n){
for (i in 2:n){
prop<-rnorm(1,mean=chain[i-1],sd=1)
if (ABC(prop)==T & prop>=0){
h_ratio<-(dgamma(prop,shape=prior_alpha,rate=prior_beta)/dgamma(chain[i-1],shape=prior_alpha,rate=prior_beta))*
(dnorm(x=chain[i-1],mean=prop,sd=1)/dnorm(x=prop,mean=chain[i-1],sd=1))
u<-runif(1)
if (min(1,h_ratio)>u) {chain[i]=prop} else {chain[i]=chain[i-1]}
}
else{chain[i]=chain[i-1]}
}
return(chain<<-chain)
}
This is more of a comment than of an answer but to keep the code formatting I'm posting as an answer.
Replace the code inside the for loop for the code below.
while(TRUE) {
prop <- rnorm(1, mean = chain[i - 1L], sd = 1)
if (ABC(prop) && prop >= 0) {
h_ratio<-(dgamma(prop,shape=prior_alpha,rate=prior_beta)/dgamma(chain[i-1],shape=prior_alpha,rate=prior_beta))*
(dnorm(x=chain[i-1],mean=prop,sd=1)/dnorm(x=prop,mean=chain[i-1],sd=1))
u<-runif(1)
if (min(1,h_ratio)>u) {chain[i]=prop} else {chain[i]=chain[i-1]}
break
} else {chain[i] <- chain[i-1]}
}
Edit
The function below seems to be what is asked for.
ABC_MCMC <- function(n){
for (i in 2:n){
# loops until condition (ABC(prop) & prop >= 0) is met
while(TRUE) {
prop <- rnorm(1, mean = chain[i-1], sd = 1)
if (ABC(prop) & prop >= 0) {
h_ratio <- (dgamma(prop, shape = prior_alpha, rate = prior_beta)/dgamma(chain[i - 1L], shape = prior_alpha, rate = prior_beta)) *
(dnorm(chain[i - 1L], prop, 1)/dnorm(prop, chain[i - 1L], 1))
u <- runif(1)
if (min(1, h_ratio) > u) {
chain[i] <- prop
} else {
chain[i] <- chain[i - 1L]
}
break
}
}
}
# function return value
chain
}

Translate matrix algebra code from VB to R

For a project, I am trying to replicate/rewrite the following Visual Basic code from a case study so I can run it in R.
For j=1 to N
For I=1 to M
While I>j
If b(I,j) c=P then
a(I,j)=l else
if b(1, j)<= [P+ (l-P ) /21 then
a(I,j)=3 else
a(1, j)=O
end if
end if
wend
while Icj
if a(I,j)=l then
a(j,i)=l else
if a(I,j)=3 then
a(j,I)=O else
a( j ,I) =3
end if
end if
wend
next
next
The goal is to compare the values b(j,I) from matrix B(M,N) and fill matrix A(M,N) with either 0,1 or 3. It should represent the results of a football game.
This is what I got so far:
M <- 3
N <- 3
A <- matrix(0,M,N)
B <- matrix(sample(0:4,25, replace=TRUE),nrow=M, ncol=N)
for (i in 1:nrow(B)) {
for (j in 1:ncol(B)) {
while (i > j) {
if (B[i,j] > B[j,i]) {
A[i,j] = 3 & A[j,i] = 0
}
if (B[i,j] < B[j,i]) {
A[i,j] = 0 & A[j,i] = 3
}
else {
A[i,j] = 1 & A[j,i] = 1
}
}
}
}
I would really appreciate any help or tips!

How to iterate over 1 <= i < j <= n elements in R?

So I am trying to do a for loop over the upper triangle part of a matrix, so I only want the elements 1 <= i < j <= n. And I tried it out in R as follows:
for(i in 1:n-1) {
for(j in i+1:n) {
...
}
}
But instead of iterating over 1 <= i < j <= n these for loops go over the elements i + 1 <= j <= i + n, 1 <= i < n.
I'm new to R, so I don't understand what is happening. Could someone give me a hint how to do it correctly?
Thanks.
for(i in seq(1, n - 1)) {
for(j in seq(i + 1, n)) {
...
}
}
alternatively
for(i in 1:(n - 1)) {
for(j in (i + 1):n) {
...
}
}
The issue is that R understands i+1:n as i + (1:n)

Couldn't calculate prime numbers within a range

for (i in 2:100 )
{
count <- 0
for (j in i )
if( (i %% j ) == 0 )
count <- count + 1
if(count == 2 )
print(i)
}
I am trying to print print prime numbers in R. Could any one help me to resolve
Let us look at your code and show what went wrong. It's the inner loop that did not loop at all:
for (i in 2:100 )
{
count <- 0
for (j in 1:i ) # you forgot to provide a vector here
if( i %% j == 0 )
count <- count + 1
if(count == 2)
print(i)
}
The answer above tries to optimise the code some more and is a more efficient solution. For example does it only test odd numbers because even ones clearly aren't prime numbers.
The below code creates the function prime_numbers which returns prime numbers up to an inputted number.
prime_numbers <- function(n) {
if (n >= 2) {
x = seq(2, n)
prime_nums = c()
for (i in seq(2, n)) {
if (any(x == i)) {
prime_nums = c(prime_nums, i)
x = c(x[(x %% i) != 0], i)
}
}
return(prime_nums)
}
else {
stop("Input number should be at least 2.")
}
}
## return the answer to your question
prime_numbers(100)
If you wanted the range 3:100, after running the above code you could run something like this:
a<-prime_numbers(100)
a[a>3]
I hope this helps!

Why does this Fibonnacci recursion fails to return an answer for n > 2?

This recursion code doesn't give an output for n > 2. It works if I include the last if condition as else. Why does this happen?
fib <- function(n){
if(n == 0){
0
}
if(n ==1 ){
1
}
if(n == 2){
1
}
if (n > 2) {
print(n)
fib(n-1) + fib(n-2)
}
}
A function by default returns the result of the last value evaluated inside the function. Here you have a bunch of separate if statements that will all be evaluated (your function doesn't return early at any point. Observe
f <- function(a) {
-99
if (a==1) {111}
if (a==2) {22}
}
f(1)
# -- doesn't return anything --
f(2)
# [1] 22
f(3)
# -- doesn't return anything --
When 'a==1', That middle if statement would evaluate to 111 but that value is then discarded when you run the next if statement just like the -99 value was before it. The last expression that was evaluated in this function is the if (a==2) {22} and that will either return 22 or it will return NULL. It won't return the previous values because it has no idea how those would be related without the else statement.
fib <- function(n){
if(n == 0){
return(0)
}
if(n ==1 ){
return(1)
}
if(n == 2){
return(1)
}
if (n > 2) {
print(n)
return(fib(n-1) + fib(n-2))
}
}
Or you could turn those into if/else staments so only one "thing" will be returned
fib <- function(n){
if(n == 0){
0
} else if(n ==1 ){
1
} else if(n == 2){
1
} else if (n > 2) {
print(n)
fib(n-1) + fib(n-2)
}
}

Resources