I have written the following loop in R. I want the loop to keep running until there is a case where Y is greater than or equal to 3. I then want to display T which is the number of experiments run until this outcome occurs for the first time.
T=0
while(Y<3)
{
X=rbinom(1,5,0.5)
Y=rbinom(1,X,0.5)
Outcome=Y
T=T+1
}
T
I am very new to R and I'm unsure how to change what i've done to achieve what I need.
You can use a do until construction:
while(TRUE){
# Do things
if(Y >= 3) break()
}
You don't need a loop for this. The following uses R's vectorization and is much more efficient.
set.seed(42) #for reproducibility
n <- 1e4 #increase n and rerun if condition is never satisfied
X=rbinom(n,5,0.5)
Y=rbinom(n,X,0.5)
#has condition been satisfied?
any(Y>3)
#TRUE
#first value that satisfies the condition
which.max(Y>3)
#[1] 141
If you don't know how many times you are to perform the loop, while loop is used in that case. It performs the looping until your desired condition is satisfied. You can try the following codes.
T=0 #Index variable
Y=2 #Initial value that starts the while looping
At first while loop inspect this initial Y=2, if it satisfies the condition then the lopping starts until the condition gets dissatisfied.
while(Y<3) #Initialization of your looping
{
X=rbinom(1,5,0.5)
Y=rbinom(1,X,0.5)
T=T+1
}
T
The first time the while checks its condition it does not find Y. Try to initialize Y to something less than 3.
Y <- 0
Related
Inspired by the leetcode challenge for two sum, I wanted to solve it in R. But while trying to solve it by brute-force I run in to an issue with my for loop.
So the basic idea is that given a vector of integers, which two integers in the vector, sums up to a set target integer.
First I create 10000 integers:
set.seed(1234)
n_numbers <- 10000
nums <- sample(-10^4:10^4, n_numbers, replace = FALSE)
The I do a for loop within a for loop to check every single element against eachother.
# ensure that it is actually solvable
target <- nums[11] + nums[111]
test <- 0
for (i in 1:(length(nums)-1)) {
for (j in 1:(length(nums)-1)) {
j <- j + 1
test <- nums[i] + nums[j]
if (test == target) {
print(i)
print(j)
break
}
}
}
My problem is that it starts wildly printing numbers before ever getting to the right condition of test == target. And I cannot seem to figure out why.
I think there are several issues with your code:
First, you don't have to increase your j manually, you can do this within the for-statement. So if you really want to increase your j by 1 in every step you can just write:
for (j in 2:(length(nums)))
Second, you are breaking only the inner-loop of the for-loop. Look here Breaking out of nested loops in R for further information on that.
Third, there are several entries in nums that gave the "right" result target. Therefore, your if-condition works well and prints all combination of nums[i]+nums[j] that are equal to target.
We have to create function(K) that returns vector which has all items smaller than or equal to K from fibonacci sequence. We can assume K is fibonacci item. For example if K is 3 the function would return vector (1,1,2,3).
In general, a for loop is used when you know how many iterations you need to do, and a while loop is used when you want to keep going until a condition is met.
For this case, it sounds like you get an input K and you want to keep going until you find a Fibonacci term > K, so use a while loop.
ans <- function(n) {
x <- c(1,1)
while (length(x) <= n) {
position <- length(x)
new <- x[position] + x[position-1]
x <- c(x,new)
}
return(x[x<=n])
}
`
Tried many different loops, and this is closest I get. It works with every other number but ans(3) gives 1,1,2 even though it should give 1,1,2,3. Couldn't see what is wrong with this.
What i am trying to accomplish in the forloop and am still having difficulty with:
prb[i]=(prb[i-1]*ER)+b[i]
prb[1]=(prb[0]*ER)+b[1]
prb[2]=(prb[1]*ER)+b[2]
and then output prb[1,2,3....] from the left hand side of the equation.
Also, defining SS to reflect prb at the previous time step (i.e. (prb-1))
I have attempted to save the results from my forloop in the empty vectors. However, the values outputted into the vectors are the same values(i.e. from the first iteration) and it doesn't appear to be having the additive affect I am attempting. Somethings appears to be wrong with the logic of my code. I would like for the values from b[i] to be used in b[i+1] for the next run of the forloop. Does anyone have any ideas or solutions to problem? Best!
Matthew
#Parameters
c=0.2
A=5
d=8
d0=5
s=0.5
e=0.1
p=0.6
ER=e/A
#Colonization Equation Probabilities
C2 = c*A*exp(-d*s/d0) #ML to SS
#Empty Vectors
l=vector(mode="numeric", length=100) #open vectors to store the different probability values from the forloop
b=vector(mode="numeric", length=100)
prb=(l*ER) + b #total probability of SS being colonized
#Island States
ML=1
SS=prb
n.I=c(ML, SS)
#Forloop and Conditional Statements
for(i in 2:101) {
(SS[i]=prb[i-1])
(prb[i]=(l[i]*ER)+b[i])
if (SS < 1 ) {
(l[i]=prb[i-1])
} else if(SS < 1){
b[i]=C2
}
}
I copied your code and ran it. My observations are:
First of all, in R, vector indices start from 1 not 0.
So SS=prb[0:1] yields prb[0] which is just 0.
Since to execute the line for populating prb is conditional on SS being >= 1, you can never run this line with this condition. When prb[1] is not 1 or larger, you cannot alter it so there is a vicious circle.
Even if you can run it by satisfying the condition (a different one of course), since for the first iteration prb[0] is non existent so prb[0]*ER just yields numeric(0), which is an empty vector item!
So first you should modify your vector indices, then you should modify your condition so that it allows for a jump start.
I've tried a couple ways of doing this problem but am having trouble with how to write it. I think I did the first three steps correctly, but now I have to fill the vector z with numbers from y that are divisible by four, not divisible by three, and have an odd number of digits. I know that I'm using the print function in the wrong way, I'm just at a loss on what else to use ...
This is different from that other question because I'm not using a while loop.
#Step 1: Generate 1,000,000 random, uniformly distributed numbers between 0
#and 1,000,000,000, and name as a vector x. With a seed of 1.
set.seed(1)
x=runif(1000000, min=0, max=1000000000)
#Step 2: Generate a rounded version of x with the name y
y=round(x,digits=0)
#Step 3: Empty vector named z
z=vector("numeric",length=0)
#Step 4: Create for loop that populates z vector with the numbers from y that are divisible by
#4, not divisible by 3, with an odd number of digits.
for(i in y) {
if(i%%4==0 && i%%3!=0 && nchar(i,type="chars",allowNA=FALSE,keepNA=NA)%%2!=0){
print(z,i)
}
}
NOTE: As per #BenBolker's comment, a loop is an inefficient way to solve your problem here. Generally, in R, try to avoid loops where possible to maximise the efficiency of your code. #SymbolixAU has provided an example of doing so here in the comments. Having said that, in aid of helping you learn the ins-and-outs of loops and vectors, here's a solution which only requires a change to one line of your code:
You've got the vector created before the loop, that's a good start. Now, inside your loop, you need to populate that vector. To do so, you've currently got print(z,i), which won't really do too much. What you need to to change the vector itself:
z <- c( z, i )
Should work for you (just replace that print line in your loop).
What's happening here is that we're taking the existing z vector, binding i to the end of it, and making that new vector z again. So every time a value is added, the vector gets a little longer, such that you'll end up with a complete vector.
where you have print put this instead:
z <- append(z, i)
I have got a column with different numbers (from 1 to tt) and would like to use looping to perform a count on the occurrence of these numbers in R.
count = matrix(ncol=1,nrow=tt) #creating an empty matrix
for (j in 1:tt)
{count[j] = 0} #initiate count at 0
for (j in 1:tt)
{
for (i in 1:N) #for each observation (1 to N)
{
if (column[i] == j)
{count[j] = count[j] + 1 }
}
}
Unfortunately I keep getting this error.
Error in if (column[i] == j) { :
missing value where TRUE/FALSE needed
So I tried:
for (i in 1:N) #from obs 1 to obs N
if (column[i] = 1) print("Test")
I basically got the same error.
Tried to do abit research on this kind of error and alot have to said about "debugging" which I'm not familiar with.
Hopefully someone can tell me what's happening here. Thanks!
As you progress with your learning of R, one feature you should be aware of is vectorisation. Many operations that (in C say) would have to be done in a loop, can be don all at once in R. This is particularly true when you have a vector/matrix/array and a scalar, and want to perform an operation between them.
Say you want to add 2 to the vector myvector. The C/C++ way to do it in R would be to use a loop:
for ( i in 1:length(myvector) )
myvector[i] = myvector[i] + 2
Since R has vectorisation, you can do the addition without a loop at all, that is, add a scalar to a vector:
myvector = myvector + 2
Vectorisation means the loop is done internally. This is much more efficient than writing the loop within R itself! (If you've ever done any Matlab or python/numpy it's much the same in this sense).
I know you're new to R so this is a bit confusing but just keep in mind that often loops can be eliminated in R.
With that in mind, let's look at your code:
The initialisation of count to 0 can be done at creation, so the first loop is unnecessary.
count = matrix(0,ncol=1,nrow=tt)
Secondly, because of vectorisation, you can compare a vector to a scalar.
So for your inner loop in i, instead of looping through column and doing if column[i]==j, you can do idx = (column==j). This returns a vector that is TRUE where column[i]==j and FALSE otherwise.
To find how many elements of column are equal to j, we just count how many TRUEs there are in idx. That is, we do sum(idx).
So your double-loop can be rewritten like so:
for ( j in 1:tt ) {
idx = (column == j)
count[j] = sum(idx) # no need to add
}
Now it's even possible to remove the outer loop in j by using the function sapply:
sapply( 1:tt, function(j) sum(column==j) )
The above line of code means: "for each j in 1:tt, return function(j)", an returns a vector where the j'th element is the result of the function.
So in summary, you can reduce your entire code to:
count = sapply( 1:tt, function(j) sum(column==j) )
(Although this doesn't explain your error, which I suspect is to do with the construction or class of your column).
I suggest to not use for loops, but use the count function from the plyr package. This function does exactly what you want in one line of code.