I have the below existing code in R. The code prints the next immediate prime number. I want to consider inclusive of starting number
np <- function(x){
if (x==1L | x==2L) {return(2L)}
else {
temp <- x+1
test <- 2:x
while( any( (temp %% test) == 0 ) ){
temp <- temp+1
}
temp
} }
Eg.. np(7) returns 11. But expected output is 7.
Try the code below (following a similar idea in the answer here)
np <- function(x) {
p <- x
repeat {
if (p %in% c(2, 3) | all(p %% ceiling(sqrt(2:p)) != 0)) {
return(p)
}
p <- p + 1
}
}
and you will see
> np(2)
[1] 2
> np(3)
[1] 3
> np(4)
[1] 5
> np(5)
[1] 5
> np(7)
[1] 7
Maybe it's stupid but does this do the trip?
np <- function(x){
if (x==1L | x==2L) {return(2L)}
else {
x= x-1
temp <- x+1
test <- 2:x
while( any( (temp %% test) == 0 ) ){
temp <- temp+1
}
temp
} }
You are testing numbers above x only by calling temp <- x+1. Here is a version that should work with minimal changes to your code:
np <- function(x){
if (x==1L | x==2L) {return(2L)}
else {
temp <- x
test <- 2:(x - 1)
while( any( (temp %% test) == 0 ) ){
temp <- temp+1
}
temp
} }
Related
here is the code for a simulation I'm trying to run:
n_draws <- 1000
black <- rep(0, n_draws)
hispanic <- rep(0, n_draws)
asian <- rep(0, n_draws)
white <- rep(0, n_draws)
cutoff <- c(0.05,0.1,0.25,1)
draws <- runif(n_draws,0,1)
for (i in draws){
if (draws[i] < cutoff[1]){
black[i] <- 1
} else if ((draws[i] >= cutoff[1]) & (draws[i] < cutoff[2])){
hispanic[i] <- 1
} else if ((draws[i] >= cutoff[2]) & (draws[i] < cutoff[3]){
asian[i] <- 1
} else {
white[i] <- 1
}
}
Basically, I want to add a 1 to the corresponding list, conditional on where that number falls in the range (0,1). I'm not sure why this is giving an error. Suggestions?
You're just missing a closing bracket just after cutoff[3], also used seq_along in my example as it's a bit nicer
for (i in seq_along(draws)){
if (draws[i] < cutoff[1]){
black[i] <- 1
} else if ((draws[i] >= cutoff[1]) & (draws[i] < cutoff[2])){
hispanic[i] <- 1
} else if ((draws[i] >= cutoff[2]) & (draws[i] < cutoff[3])){
asian[i] <- 1
} else {
white[i] <- 1
}
}
I'm making a function that categorize the customers based on there sales into 3 classes A,B and C, but the function give me wired results i don't know why
f <- function(x)
{
for(j in 1:length(x))
{
if(x[j] > 0 & x[j] < 501 )
{
x[j] = "C"
}
else if(x[j] > 500 & x[j] < 1001 )
{
x[j] = "B"
}
else if(x[j] > 1000 )
{
x[j] = "A"
}
}
return(x)
}
This is the function.
print(f(c(2000,2000,2000)))
when i run this for example it gave me A,C,C where is should be all A
print(f(c(600,600)))
this gave B which is right but then A !
As noted by #shwan you were rewriting the x vector as character values. To avoid defining an other vector for result and also avoid the loop structure you could just use the vectorized ifelse command and write your function as:
f=function(x){ifelse(x>0 & x<501,"A",ifelse(x>500 & x <1001,"B","C"))}
By using x[j] = "C", you are coercing x to class 'character', which then returns unexpected logical comparisons.
You need to save the result in some other, character vector ('ret' below).
f <- function(x) {
ret <- NA_character_
for(j in 1:length(x)) {
if(x[j] > 0 & x[j] < 501 ) {
ret <- c(ret,"C")
} else if(x[j] > 500 & x[j] < 1001 ) {
ret <- c(ret,"B")
} else if(x[j] > 1000 ) {
ret <- c(ret,"A")
}
}
ret <- ret[2:length(ret)] # remove the first element
return(ret)
}
I am learning about loops and I have this code to check if a number is prime or not, but doesn't work. Where is the bug?
x <- 7
y <- seq(1,sqrt(x),by=1)
for(i in 1: sqrt(x)){
if(y[x%%y == 0]) {
print("FALSE")
}else{
print("TRUE")
}
}
This gives me the right solution, but it repeats the answer as many times as number of elements in i. Also I would like to ask how to use function inside a for with if:
i <- c(1: sqrt(x))
y3 <- x%%i == 0
y4 <- y3[-1]
for(value in i){
if(y4 == FALSE) {
print("TRUE")
}else{
print("FALSE")
}
}
version 3, gives me the solution but for evey element in i:
x <- 107
i <- c(1: sqrt(x))
y3 <- c(x%%i == 0)
y4 <- y3[-1]
for(value in i){
if(all(y4==F)) {
print("TRUE")
}else{
print("FALSE")
}
}
Since you mentioned that you must use a loop, the following code will work:
x <- 7
y <- seq(1, ceiling(sqrt(x)), by=1)
# is.factor is a vector which checks whether each element in y is a factor or not
# initialize to F
is.factor = F
# Start at y = 2 because 1 will be a factor
for(i in 2:length(y) ){
# Check whether current value in vector is a factor of x or not
# if not a factor, set value in index to F, otherwise set to T
ifelse( x%%y[i] != 0, is.factor[i] <- F, is.factor[i] <- T)
# If we are at the last element in y, print a result
if(i == length(y)){
# check if we have any factors.
# if we have any factors (i.e. any index in is.factor vector is T), then number is not prime
ifelse( any(is.factor), print("FALSE"), print("TRUE") )
}
}
You can do this-
check_prime <- function(num) {
if (num == 2) {
TRUE
} else if (any(num %% 2:(num-1) == 0)) {
FALSE
} else {
TRUE
}
}
> check_prime(7)
[1] TRUE
I've got the following code in R:
func.time <- function(n){
times <- c()
for(i in 1:n){
r <- 1 #x is the room the mouse is in
X <- 0 #time, starting at 0
while(r != 5){
if(r == 1){
r <- sample(c(2,3),1) }
else if(r == 2){
r <- sample(c(1,3), 1) }
else if(r == 3){
r <- sample(c(1,2,4,5), 1) }
else if (r == 4){
r <- sample(c(3,5), 1) }
X <- X + 1
}
times <- c(X, times)
}
mean(times)
}
func.time(10000)
It works fine, but I've been told that using switch() can speed it up seeing as I've got so many if else statements but I can't seem to get it to work, any help is appreciated in advance.
Edit
I've tried this:
func.time <- function(n) {
times <- c()
for(i in 1:n) {
r <- 1 #x is the room the mouse is in
X <- 0 #time, starting at 0
while(r != 5) {
switch(r, "1" = sample(c(2,3), 1),
"2" = sample(c(1,3), 1),
"3" = sample(c(1,2,4,5), 1),
"4" = sample(c(3,5)))
X <- X + 1
}
times <- c(X, times)
}
mean(times)
}
func.time(10000)
But it was a basic attempt, I'm not sure I've understood the switch() method properly.
I though Dominic's assessment was very useful but when I went to examine the edit it was being held up on what I thought was an incorrect basis. So I decided to just fix the code. When usign a numeric argument to the EXPR parameter you do not use the item=value formalism but rather just put in the expressions:
func.time <- function(n){times <- c()
for(i in 1:n){; r <- 1; X <- 0
while(r != 5){
r <- switch(r,
sample(c(2,3), 1) , # r=1
sample(c(1,3), 1) , # r=2
sample(c(1,2,4,5), 1), #r=3
sample(c(3,5), 1) ) # r=4
X <- X + 1 }
times <- c(X, times) }
mean(times) }
func.time(1000)
#[1] 7.999
For another example of how to use switch with a numeric argument to EXPR, consider my answer to this question: R switch statement with varying outputs throwing error
I have generated an infinite loop and don't know how to fix it.
I essentially want to go through the data frame rnumbers and generate rstate2 with 1, -1, or 0 depending on what is in rnumbers
The function step_generator is getting stuck at the repeat function. I am not sure how to make the code put -1 in rstate2 if rnumber is less than C and then repeat an ifelse function for the next rows until a value of D or greater is obtained. Once D is obtained exit the repeat function and go back into the original for loop.
Here is my code:
rnumbers <- data.frame(replicate(5,runif(20000, 0, 1)))
dt <- c(.01)
A <- .01
B <- .0025
C <- .0003
D <- .003
E <- .05
rstate <- rnumbers # copy the structure
rstate[] <- NA # preserve structure with NA's
# Init:
rstate[1, ] <- c(0)
step_generator <- function(col, rnum){
for (i in 2:length(col) ){
if( rnum[i] < C) {
col[i] <- -1
repeat {
ifelse(rnum[i] < E, -1, if(rnum[i] >= D) {break})
}
}
else { if (rnum[i] < B) {col[i] <- -1 }
else {ifelse(rnum[i] < A, 1, 0) } }
}
return(col)
}
# Run for each column index:
for(cl in 1:5){ rstate[ , cl] <-
step_generator(rstate[,cl], rnumbers[,cl]) }
Thanks for any help.
The problem is that you are not increasing i inside repeat loop, so basically you are testing the same i all the time, and because rnum[i] < C (from if condition) it will always be rnum[i] < E since C < E, and loop never breaks.
However, if you increase i inside repeat it still will come back to value resulting from for loop, so you have to do it in different way, for example using while loop. I'm not exactly sure if I understand what you are trying to do, but basing on your description I've made this function:
step_generator <- function(col, rnum){
i <- 2
while (i <= length(col)){
if (rnum[i] < C) {
col[i] <- -1
while ((i < length(col)) & (rnum[i + 1] < D)){
i <- i + 1
col[i] <- -1
}
} else if (rnum[i] < B){
col[i] <- -1
} else if (rnum[i] < A){
col[i] <- 1
} else {
col [i] <- 0
}
i <- i + 1
}
return(col)
}