I have a code to make a game where a person rolls the die 4 times and if a roll lands on 6, they win. However, I'm running the code but it doesn't produce an output.
game<-function (n=4){
count=0
ceiling(6*runif(1))
for(i in 1:n){
if(ceiling(6*runif(1))==6){
count=1
}
else(
count=0
)
if(count=1){
print("Win")}
else{
print("Lose")
}
}
}
You can in fact do it much simpler using ifelse to vectorise the if statement. Also, you can avoid intermediate variables (e.g. count):
game<-function (n=4){
ifelse(6 %in% sample(6, n, replace = TRUE), "Win", "Lose")
}
I would suggest using any to see if any roll equals to 6, then use return to report the value.
game <- function(n = 4){
if (any(ceiling(6 * runif(n)) == 6L)){
return("Win")
} else {
return("Lose")
}
}
Related
I am trying to define a function with a for loop and inside a conditional in R studio. Yesterday I was able with the help of another thread to devise this piece of code. The problem is that I want to sum the vector elements ma for any possible x, so that is inside the function l. This is a simpler case which I am trying to solve to adapt the original model. However, I do not know how to proceed.
ma<-rep(0,20)
l <- function(x, ma) {
for(i in seq_along(ma)) {
if(i %% 2 == 1) {
ma[i] <- i + x
} else {
ma[i] <- 0
}
}
return(ma)
}
My problem is that I would like to have the sum of i+x+0+i+x... for any possible x. I mean a function of the kind for any possible x.
Question:
Can someone explain to me how to implement such a function in R?
Thanks in advance!
I am going to update the original function:
Theta_alpha_s<-function(s,alpha,t,Basis){
for (i in seq_along(Basis)){
if(i%% 2==1) {Basis[i]=s*i^{-alpha-0.5}*sqrt(2)*cos(2*pi*i*t)}
else{Basis[i]=s*i^{-alpha-0.5}*sqrt(2)*sin(2*pi*i*t)}
}
return(Basis)
}
If you don't want to change the values in Basis, you can create a new vector in the function (here result) that you will return:
l = function(s,alpha,t,Basis){
is.odd = which(Basis %% 2 == 1)
not.odd = which(Basis %% 2 == 0)
result = rep(NA, length(Basis))
result[is.odd] = s*is.odd^{-alpha-0.5}*sqrt(2)*cos(2*pi*is.odd*t)
result[not.odd] = s*not.odd^{-alpha-0.5}*sqrt(2)*sin(2*pi*not.odd*t)
#return(result)
return(c(sum(result[is.odd]), sum(result[not.odd])))
}
I have a question how to make a IF
for (i in 1:12){
for (j in 1:12) {
if (i != j) {
var = x + b
}
else{ }
}}
"else" I need that when they are equal to continue with j + 1 example: if i = 4 and j = 4 then continue with j = 5 and continue counting until the end of j and continue the process of when i! = j
I think you don't understand what is going on in your code or you don't understand what for loops do. One "trick" you can do is to actually print what happens in your for loops so that you will have one idea of what is going on. You could also do this with a piece of paper.
As they already pointed you out, you don't need the else because the for already takes care of this.
for (i in 1:12){
print("-------------------------------")
valueI <- paste0("my i value is ",i)
print(valueI)
for (j in 1:12) {
valueJ <- paste0("my j value is ",j)
print(valueJ)
if (i != j) {
#var = x + b
diff <- paste0(i, " is different than ", j)
print(diff)
}
else{
}
}
}
This code is the same as yours and will generate a log that explains you what happens step from step, you could also use a debugger but seeing your struggles, better use this for now. What are you trying to calculate? I feel like you want to calculate the power of something...
I'm trying to improve my function writing skills and I'm a little confused on the proper structure of functions. I've searched a ton of examples, but none are that clear to me. My aim is to run the #RUN over and over section in a for loop and build a function which allows me to control the number of times I can loop it.
Currently, I've got to this point:
set.seed(123)
#Start but setting the conditions and being the Win Lose counters
Count_Win_Hunt=0
Count_Win_Moose=0
#RUN over and over
Hunter=1
Moose=7
win=0
while(win != 1){ a = sample(1:6, 1) # dice roll
if( a<= 4) {Moose = Moose+a} else{Hunter = Hunter+a}
if( Hunter >= Moose ) { Count_Win_Hunt = Count_Win_Hunt +1 } else if( Moose >= 12) {Count_Win_Moose = Count_Win_Moose + 1}
if( Hunter >= Moose || Moose >= 12 ) {win = win+1} else {
#if not condition not meet roll again
a = sample(1:6, 1) # dice roll
if( a<= 4) {Moose = Moose+a} else{ Hunter = Hunter+a}}}
# calculated the average win rates
paste0( round(Count_Win_Hunt/(Count_Win_Hunt+Count_Win_Moose),4)*100,"%"," of the time the Hunter won")
paste0( round(Count_Win_Moose/(Count_Win_Hunt+Count_Win_Moose),4)*100,"%"," of the time the Moose won")
Besides my general problems with your question (please be more specific as to your actual problem) your for-loops have a wrong syntax. They should be like this:
for (val in sequence)
{
statement
}
So applied to your function they should look like this:
for (val in c(1:4))
{
probability + (hunter,goose+val,num+1)
}
for (val in c(5:6))
{
probability + (hunter,goose+val,num+1)
print probability
}
However the are not only syntactically wrong, also their content seems to be wrong.
E.g. in your second for-loop, the goose steps forward even though it should be the hunter. Also these are not two for-loops but should be an if-statement like this:
if (val <= 4) {
probability + (hunter,goose+val,num+1)
}
else {
probability + (hunter+val,goose,num+1)
}
Finally the whole structure of your function seems strange (and has misleadingly named variables). Shouldn`t it be something like this:
dice_roll <- function(hunter,goose, win){
# While to check for winning condition
while(win != 1){
dice_roll = sample(1:6, 1) # simulate dice roll
# If statement depending on dice roll, increasing value of hunter or goose by dice roll
# Change win condition
If(hunter >= goose){
win <- 1
}
}
dice_roll(1,7,0)
I am trying to eliminate all rows in excel that have he following features:
First column is an integer
Second column begins with an integer
Third column is empty
The code I have written appears to run indefinitely. CAS.MULT is the name of my dataframe.
for (i in 1:nrow(CAS.MULT)) {
testInteger <- function(x) {
test <- all.equal(x, as.integer(x), check.attributes = FALSE)
if (test == TRUE) {
return (TRUE)
}
else {
return (FALSE)
}
}
if (testInteger(as.integer(CAS.MULT[i,1])) == TRUE) {
if (testInteger(as.integer(substring(CAS.MULT[i,2],1,1))) == TRUE) {
if (CAS.MULT[i,3] == '') {
CAS.MULT <- data.frame(CAS.MULT[-i,])
}
}
}
}
You should be very wary of deleting rows within a for loop, if often leads to undesired behavior. There are a number of ways you could handle this. For instance, you can flag the rows for deletion and then delete them after.
Another thing I noticed is that you are converting your columns to integers before passing them to your function to test if they are integers, so you will be incorrectly returning true for all values passed to the function.
Maybe something like this would work (without a reproducible example it's hard to say if it will work or not):
toDelete <- numeric(0)
for (i in 1:nrow(CAS.MULT)) {
testInteger <- function(x) {
test <- all.equal(x, as.integer(x), check.attributes = FALSE)
if (test == TRUE) {
return (TRUE)
}
else {
return (FALSE)
}
}
if (testInteger(CAS.MULT[i,1]) == TRUE) {
if (testInteger(substring(CAS.MULT[i,2],1,1)) == TRUE) {
if (CAS.MULT[i,3] == '') {
toDelete <- c(toDelete, i)
}
}
}
}
CAS.MULT <- CAS.MULT[-1*toDelete,]
Hard to be sure without testing my code on your data, but this might work. Instead of a loop, the code below uses logical indexing based on the conditions you specified in your question. This is vectorized (meaning it operates on the entire data frame at once, rather than by row) and is much faster than looping row by row:
CAS.MULT.screened = CAS.MULT[!(CAS.MULT[,1] %% 1 == 0 |
as.numeric(substring(CAS.MULT[,2],1,1)) %% 1 == 0 |
CAS.MULT[,3] == ""), ]
For more on checking whether a value is an integer, see this SO question.
One other thing: Just for future reference, for efficiency you should define your function outside the loop, rather than recreating the function every time through the loop.
Background
I'm developing a function that takes in a value for w between 1 and 3 and returns n values from one of 3 distributions.
The problem I am having is when n or w are not of length 1. So I've added 2 parameters nIsList and wIsList to create the functionality I want. The way I want this to work is as follows:
(Works as needed)
If nIsList ex( c(1,2,3) ) return a list equivalent to running consume(w,1), consume(w,2), consume(w,3)
(Works as needed)
If wIsList ex( c(1,2,3) ) return a list equivalent to running consume(1,n), consume(2,n), consume(3,n)
(Doesn't work as needed)
If nIsList ex(1,2,3) and wIsList ex(1,2,3)
return a list equivalent to running consume(1,1), consume(2,2), consume(3,3). Instead, I get a list equivalent to running [consume(1,1), consume(1,2), consume(1,3)], [consume(2,1), consume(2,2), consume(2,3)], [consume(3,1),consume(3,2), consume(3,3)]
I understand why I am getting the results I am getting. I just can't seem to figure out how to get the result I want. (As explained above)
Question
I want the function to provide a list for each element in w and n that is consume(w[i], n[i]) when wIsList & nIsList are True. Is there a way to do that using lapply?
The code:
library("triangle")
consume <- function(w, n=1, nIsList=F, wIsList=F){
if(!nIsList & !wIsList){
if(w==1){
return(rtriangle(n,0.3,0.8))
}else if(w==2){
return(rtriangle(n,0.7,1))
}else if(w==3){
return(rtriangle(n,0.9,2,1.3))
}
}
else if(nIsList & !wIsList){
return(sapply(n, consume, w=w))
}
else if(nIsList & wIsList){
return(lapply(n, consume, w=w, wIsList=T))
}
else if(!nIsList & wIsList){
return(lapply(w, consume, n))
}
}
Note: I am having trouble summarizing this question. If you have any suggestions for renaming it please let me know and I will do so.
Thanks to JPC's comment, using mapply does the trick. The new code is as follows:
consume <- function(w, n=1){
nIsList <- length(n) > 1 # Change based on JPC's second comment
wIsList <- length(w) > 1 # Change based on JPC's second comment
if(!nIsList & !wIsList){
if(w==1){
return(rtriangle(n,0.3,0.8))
}else if(w==2){
return(rtriangle(n,0.7,1))
}else if(w==3){
return(rtriangle(n,0.9,2,1.3))
}
}
else if(nIsList & !wIsList){
return(sapply(n, consume, w=w))
}
else if(nIsList & wIsList){
return(mapply(consume,w,n)) ## Updated portion
}
else if(!nIsList & wIsList){
return(lapply(w, consume, n))
}
}