I made a thread about this earlier although it got closed since I was unclear. I will try to be more clear now.
What I'm wondering is, if you enter my code into Rstudio, it will give you a graph. On the x-axis there are 6 bars (6 different states), and on the y-axis is the frequency 0-300. All I can see is that state 1 is somewhere in-between 0 and 50. Is there any code that can let me exactly what value state 1 and the others states have?
Here is a matrix:
spec_sim <- function(x){
u <- runif(1)
if(x==0){ if(u < 0.5){ y <- 3
} else{
y <- 5
}
} else if(x==1){
if(u<0.1){
y <- 0
} else if(u < 0.1 + 0.1){
y <- 1
} else if(u < 0.1 + 0.1 + 0.4){
y <- 3
} else{
y <- 5
}
} else if(x==2){
if(u<0.2){
y <- 1
} else if(u < 0.2 + 0.2){
y <- 2
} else if(u < 0.2 + 0.2 + 0.3){
y <- 3
} else{
y <- 5
}
} else if(x==3){
if(u<0.3){
y <- 2
} else if(u < 0.3 + 0.5){
y <- 3
} else{
y <- 5
}
} else if(x==4){
if(u<0.4){
y <- 3
} else{
y <- 4
}
} else if(x==5){
if(u<0.4){
y <- 4
} else{
y <- 5
}
}
y
}
set.seed(1)
results <- numeric(1001)
for(i in 2:length(results)){
results[i]<- spec_sim(results[i - 1])
}
results <- results[-1]
barplot(table(results), xlab="states", ylab="frequency",
main="1000 simuleringar av en Markovkedja")
To identify the value in an active plotting device (window), you use ?identify. Since the data to be plotted were from a table that was created (but not saved to an object) within the plotting command, you need to enter that for the x and labels arguments to the function. Once you run the command, the mouse pointer will display as a plus over the plotting device. Then you just click on the bar you want. Consider:
identify(table(results), labels=table(results))
The value for 1 is evidently 26.
This is a very general method for getting values from a plot. Of course, you can also just inspect the underlying data object. That is more straightforward in this case:
table(results)
# results
# 0 1 2 3 4 5
# 4 26 112 306 296 256
Related
I am trying to find Previous Prime number of given value. The mentioned code works fine if I pass prime Number straight away as input lp(7) returns 7. But if I pass lp(6) none are displaying. I am expecting 5 to return.
How do I find the previous prime Number for given one.
Suggestions / Corrections are much appreciated
lp <- function(x){
temp <- x:2
while (x == 2L || all(x %% 2L:max(2,floor(sqrt(x))) != 0))
{
return(x)
}
}
If you run this function a lot of times, probably most efficient is to generate a list of primes once, and search where your value lies in that sequence
library(primes)
primes = generate_primes(2, 1e6)
find_lower_prime = function(x) {
primes[findInterval(x, primes)]
}
find_lower_prime(6)
# [1] 5
You can use the following
lp <- function(x){
previousNumbers <- 2:x
previousPrimes <- sapply(previousNumbers, function(num) {
divisorsToCheck <- 2:max(2,floor(sqrt(num)))
if(num == 2 | all(num %% divisorsToCheck != 0)) {
return(num)
} else {
return(NA)
}
})
previousPrimes[!is.na(previousPrimes)]
}
to get all previous primes.
lp(18) # 2 3 5 7 11 13 17
lp(5) #2 3 5
You can try the code lie below
lp <- function(x) {
p <- x - 1
repeat {
if (p %in% c(2, 3) | all(p %% ceiling(sqrt(2:p)) != 0)) {
return(p)
}
p <- p - 1
}
}
and you will see
> lp(5)
[1] 3
> lp(6)
[1] 5
> lp(7)
[1] 5
> lp(8)
[1] 7
> lp(11)
[1] 7
Hi All this worked for me ..
lp <- function(x){
for(i in x:2)
{
while (i == 2L || all(i %% 2L:max(2,floor(sqrt(i))) != 0))
{
return(i)
}
}
}
I have confused about this for the past hour and may someone help me out.
Here is my code, where I attempt to create 2 functions that are to be used in a tibble().
n <- 1000
w <- function(x) {
if(-2 <= x & x <= 2) {
return((-3/32)*x^2 + 3/8)
}else{
return(0)
}
}
y <- function(x){
if(0 <= x & x <= 8){
return((1/8)*x^(-2/3) - (1/32))
}else{
return(0)
}
}
df <- tibble(value = seq(2, 9, length.out = n), W = w(value), Y = y(value))
head(df)
As you see, W returns a negative value when values are greater than 2, but in my function w(), there is an if statement to restrict that from happening.
So what's going and how do I solve this issue?
You have used if/else which works for single input (scalar) and you are passing multiple values to it (vector). You should use ifelse which is vectorised.
IfI have understood you correctly in w you want to apply the formula (-3/32)*x^2 + 3/8 but if a value is negative assign as 0. Same for y where you want to apply formula (1/8)*x^(-2/3) - (1/32). You can change your function to.
w <- function(x) {
pmax((-3/32)*x^2 + 3/8, 0)
}
y <- function(x){
pmax((1/8)*x^(-2/3) - (1/32), 0)
}
df <- tibble(value = seq(2, 9, length.out = n), W = w(value), Y = y(value))
head(df)
pmax selects maximum of both the inputs passed. For example,
pmax(-5:5, 0)
#[1] 0 0 0 0 0 0 1 2 3 4 5
Here's code that does what you want to a much smaller test case that still allows looking across the full extent of the ranges of you values (I took the liberty of expanding the range of testing for values because the original case where x was between -2 and 2 had only one instance and that gave 0 for w(2) regardless.
n <- 10
w <- function(x) {
ifelse( -2 <= x & x <= 3 , (-3/32)*x^2 + 3/8, 0)
}
y <- function(x){
ifelse (0 <= x & x <= 8, (1/8)*x^(-2/3) - (1/32), 0)
}
df <- tibble(value = seq(2, 9, length.out = n), W = w(value), Y = y(value))
#-----------
df
# A tibble: 10 x 3
value W Y
<dbl> <dbl> <dbl>
1 2 0 0.0475
2 2.78 -0.348 0.0320
3 3.56 0 0.0224
4 4.33 0 0.0158
5 5.11 0 0.0109
6 5.89 0 0.00708
7 6.67 0 0.00404
8 7.44 0 0.00154
9 8.22 0 0
10 9 0 0
Earlier observations:
Your code threw an error and I addressed it by making a couple of minor adjustments to the w function:
w <- function(x) {
if( (-2 <= x) && (x <= 2)) {
(-3/32)*x^2 + 3/8)
} else { 0 }
}
I think the use of ‘return’ might have been causing problems.
The expression in your first version threw this error:
Error: unexpected '<=' in:
"w <- function(x) {
if(-2 <= x <="
... because the mathematically sensible -2 <= x <= 2 just isn't parse-worthy in R.
I want to stop the counting process for y after it first time meet the condition of y < 0 for each i in the for loop. Which means, the counting process for x will still continue as long as x > 0 (condition stated in the while loop).
I had tried to do something which is if (y < 0 & (y - 120*(16/81)*time + (z-2)) > 0 & z > 2), it make sense for me but the result doesn't make sense because after I run the code, count_x is around 100 (make sense) but count_y is more than 1000 which doesn't make sense since the for loop is only from 1:1000.
count_x <- 0
count_y <- 0
for (i in 1:1000){
x <- 25
y <- 25
t <- 0
while ((x > 0 | y > 0) & t < 100){
time <- rexp(1,100)
u <- runif(1,0,1)
z <- 4/((1-u)^0.2) - 4
if (z < 2){
x <- x + 110*(65/81)*time - z
} else {
y <- y + 120*(16/81)*time - (z-2)
x <- x + 110*(65/81)*time - 2
}
t <- t + time
if (x < 0){
count_x <- count_x + 1
}
if (y < 0 & (y - 120*(16/81)*time + (z-2)) > 0 & z > 2){
count_y <- count_y + 1
}
}
}
For example, during the 1st iteration i=1, the while loop will start and run the code inside the loop. So what I want to do is:
When y first time reach negative value in the first iteration, it will update the count_y by one, then the whole if loop for the counting process of y will stop doing any thing even though the while loop is still continue to run since the if loop for counting process of x might not reach it first negative value yet (the condition for the while loop still satisfied if t is still smaller than 100), so the while loop need to be continue without touching last inner if loop until either t>100 first or x first time reach its negative value. Once, the conditions for while loop do not satisfied, then only go for the 2nd iteration i=2.
Same thing goes to x, the counting process for x will stop doing anything once x first time become a negative value but the while loop will continue working as long as the condition for the while loop still satisfied.
So, there will only be one time update for either x or y for each iteration (so maximum for y should be 1000 since we have 1000 iteration, although unlikely to reach 1000) since the counting process for both x and y will stop once it reaches the first negative value.
I'm thinking to add break function into it but not sure where should I add.
I don't think there's anything wrong with the code. The y counter, to me at least, seems like it is correct. The reason why y is larger is two-fold. Firstly, even though the outer for loop is only 1000, the inner while loop could potentially run for more than a 100 at each i iteration. Secondly, it appears that y goes below 0 before x does, hence why the x counter is smaller.
I've modified your code to include a counter that counts how many while iterations occur, and two variables that store the values of x and y respectively, the first time that y goes below zero.
count_x <- 0
count_y <- 0
while_count <- 0
store_x <- 0
store_y <- 0
a <- 1
b <- 1
for (i in 1:1000){
x <- 25
y <- 25
t <- 0
count_while <- 0
while ((x > 0 | y > 0) & t < 100){
time <- rexp(1,100)
u <- runif(1,0,1)
z <- 4/((1-u)^0.2) - 4
if (z < 2){
x <- x + 110*(65/81)*time - z
} else {
y <- y + 120*(16/81)*time - (z-2)
x <- x + 110*(65/81)*time - 2
}
t <- t + time
if (x < 0){
count_x <- count_x + 1
}
if (y < 0 & (y - 120*(16/81)*time + (z-2)) > 0 & z > 2){
count_y <- count_y + 1
store_y[a] <- y
store_x[a] <- x
a <- a + 1
}
if (y > 0){
count_while <- count_while + 1
}
}
while_count[b] <- count_while
b <- b + 1
}
Checking the averages shows that x is almost exclusively greater than zero the first time y goes below zero. The while loop averages 163 iterations.
mean(store_x)
[1] 38.90333
mean(store_y)
[1] -2.035492
mean(while_count)
[1] 163.052
which(store_x < 0)
[1] 656
So, your counter seems correct to me, x is low simply because it rarely goes below zero. In fact, run the loop for just one iteration by setting for (i in 1:1) and run it several time, you'll find that your count_x rarely goes above zero, despite the while loop iterating over a 100 times. On the other hand, y goes below zero at least once on each i iteration.
I hope this helps!
We will create variables for both x and y that will store and track when both cross zero on each i iteration. First we will check if x or y is zero and if neg is of class NULL. If so, then this is the first negative. We store x_0 or y_0 as 1. Then when counting, we check if x_0 or y_0 is equal to one and if neg is NULL. Then we will add to the counter and record the first negative. Thereafter, the condition evaluates to FALSE.
count_x <- 0
count_y <- 0
while_x <- 0
while_y <- 0
for (i in 1:1000){
x <- 25
y <- 25
t <- 0
x_0 <- 0
y_0 <- 0
neg <- NULL
neg_x <- NULL
while ((x > 0 | y > 0) & t < 100){
time <- rexp(1,100)
u <- runif(1,0,1)
z <- 4/((1-u)^0.2) - 4
if (z < 2){
x <- x + 110*(65/81)*time - z
if (x < 0 & is.null(neg_x)){
x_0 <- 1
}
} else {
y <- y + 120*(16/81)*time - (z-2)
x <- x + 110*(65/81)*time - 2
if (x < 0 & is.null(neg_x)){
x_0 <- 1
}
if (y < 0 & is.null(neg)) {
y_0 <- 1
}
}
t <- t + time
if (x_0 == 1 & is.null(neg_x)){
count_x <- count_x + 1
neg_x <- "First Negative"
x_0 <- x_0 + 1
}
if (y_0 == 1 & is.null(neg)){
count_y <- count_y + 1
neg <- "first negative"
y_0 <- y_0 + 1
}
}
}
You can also place a counter outside the while loop. If x or y is less than 0, add to the counter. This is probably a better solution. The condition will evaluate regardless of when x or y cross below zero, as long as it went below zero, it will evaluate to TRUE
count_x <- 0
count_y <- 0
for (i in 1:1000){
x <- 25
y <- 25
t <- 0
while ((x > 0 | y > 0) & t < 100){
time <- rexp(1,100)
u <- runif(1,0,1)
z <- 4/((1-u)^0.2) - 4
if (z < 2){
x <- x + 110*(65/81)*time - z
} else {
y <- y + 120*(16/81)*time - (z-2)
x <- x + 110*(65/81)*time - 2
}
t <- t + time
}
if(x < 0) {
count_x <- count_x + 1
}
if(y < 0){
count_y <- count_y + 1
}
}
For me, count_y comes out at a 1000 in both cases. This confirms what I said previously, y goes below zero at each while iteration.
while (statement 1){
......
......
if (statement 2){
x <- x + 1
break
}
if (statement 3){
y <- y + 1
}
}
I have a pseudocode as shown above, I want to verify my understanding whether is correct or not. Is it when the statement 2 is fulfilled, the equation in the 1st if loop will still run, then it will break the if loopand never come back again even the while loop still continue going on?
I am seeking an explanation about the break function in this scenario.
In short, break stops the loop at the exact position you write it without running any of the following code. You can test this by writing some easy statements and defining x and y. message is a useful function here as you can verify which part of the code still runs.
x <- 1
y <- 1
while (x < 100){
if (x == 1){
x <- x + 1
break
}
message(x)
if (y < 100){
y <- y + 1
}
message(y)
}
In this example, the first run is already interrupted as x == 1 is true from the beginning. You will notice that no message is printed but the value for x is 2 now.
In the second example, I made up a statement which will become true after a few iterations. Messages with the value of x and y are now printed for each iteration but once y > 10 nothing is printed and the loop stops immediately.
x <- 1
y <- 1
while (x < 100){
if (y > 10){
x <- x + 1
break
}
message(x)
if (y < 100){
y <- y + 1
}
message(y)
}
The difference of break in comparison to stop for example is that it will only interrupt the inner-most loop (and that stop prints a stop/error message). Meaning that if your code sits in another loop, that outer loop will continue. For example:
for (x in 1:10) {
y <- 1
while (x < 100){
if (y > 10){
x <- x + 1
break
}
message(x)
if (y < 100){
y <- y + 1
}
message(y)
}
}
You can verify how it works with this simple example :
num <- 2
x <- 0
y<- 0
while (TRUE){
if (num %% 10 == 0){
cat('\nprinting from 1: ', num)
x <- x + 1
break
}
if (num %% 2 == 0){
cat('\nprinting from 2: ', num)
y <- y+ 1
}
num <- num + 1
}
#printing from 2: 2
#printing from 2: 4
#printing from 2: 6
#printing from 2: 8
#printing from 1: 10
x
#[1] 1
y
#[1] 4
while(TRUE) makes it run for an infinite time. Every time num is divisible by 2 y is incremented and when num is divisible by 10 it increments y and the while loop breaks.
I am looping through a variable "i" in a for loop and want to reassign a value to "i" based on the outcome of an if statement. Example below.
for (i in 1:nrow(df)) {
if (df[i, 5] > 4) {
i <- 1
} else {
df[i, 5] <- df[1, 5] - 1
}
}
The script works as expected if I manually run it multiple times, but it doesn't seem to be reassigning i correctly and/or registering it in the loop. Ideas? Suggestions? Thanks in advance!
Changing the value of i inside the loop won't change where you are in the 1:nrow(df). I think this illustrates nicely:
counter = 1
for (i in 1:3) {
cat("counter ", counter, "\n")
cat("i starts as ", i, "\n")
i = 7
cat("i is is set to ", i, "\n\n")
counter = counter + 1
}
# counter 1
# i starts as 1
# i is is set to 7
#
# counter 2
# i starts as 2
# i is is set to 7
#
# counter 3
# i starts as 3
# i is is set to 7
Maybe you should be using a while loop? I think this is what you are trying to achieve, but with no sample input, explanation, or desired output provided in your question, it's just a guess:
i <- 1
while (i <= nrow(df)) {
if (df[i, 5] > 4) {
i <- 1
} else {
df[i, 5] <- df[1, 5] - 1
i <- i + 1
}
}