-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LAB 02 #4
Comments
@sunaynagoel Thank you for that catch. Here is the error in my code. If the first selection was a car door in the open_door() function I had: if( game[ a.pick ] == "car" )
{
opened.car.door <- doors[ game == "car" & game != a.pick ]
...
opened.doors <- c( opened.car.door, opened.goat.door )
} Since we have two cars, if the contestant selects a car we only have one option left to return. It has to be a car, and cannot be the current selection. I mis-matched variable types here though: game != a.pick # should be doors != a.pick !!! Make that change to your code and it should work. I'll update the solutions. |
To be clear, update the open_door() function to: open_doors <- function( game, a.pick )
{
# reveal one car and one goat
doors <- build_doors()
if( game[ a.pick ] == "car" )
{
opened.car.door <- doors[ game == "car" & doors != a.pick ]
goat.doors <- doors[ game != "car" ]
opened.goat.door <- sample( goat.doors, size=1 )
opened.doors <- c( opened.car.door, opened.goat.door )
}
if( game[ a.pick ] == "goat" )
{
opened.car.door <- sample( doors[game=="car"], size=1 )
available.goat.doors <- doors[ game != "car" & doors != a.pick ]
opened.goat.door <- sample( available.goat.doors, size=1 )
opened.doors <- c( opened.car.door, opened.goat.door )
}
return( opened.doors ) # two numbers
} |
@lecy Thank you for the update. Even after updating the code at my end it keeps giving the same error. |
@lecy I'm curious if ImageMagick is required for our Lab 02. I noticed that it was mentioned in the lab notes, but I tried all day yesterday to get it installed and this morning and I keep running into errors. Should I abandon trying to install it and focus on the lab? Thanks! -Courtney |
@lecy After changing the way we collected data for available.door my error went away. I changed the provided code
to
For some reason the initial code was generating mismatched size of vectors. It was producing probability table but rbind had issues because of mismatched size. |
@lecy Nevermind, finally got it working! |
@castower It is not required for LAB 02 - the solutions from the simulations will be mostly analytical: results.df <- NULL # collector
for( i in 1:10000 ) # iterator
{
game.outcome <- play_game()
# binding step
results.df <- rbind( results.df, game.outcome )
}
table( results.df ) %>%
prop.table( margin=1 ) %>%
round( 2 )
## outcome
## strategy LOSE WIN
## stay 0.66 0.34
## switch 0.34 0.66 Q1: Is SWITCH still the dominant strategy? Report your chances of winning for each strategy for each scenario. I am looking for you to report on changes to the probability of winning given each strategy as the game changes. You are welcome to create an animation of the game, though !!! |
Does this outcome look right for the 5 doors game (3 goats and 2 cars)? |
With stay, you have a 2 in 5 shot of guessing correctly first time. So 40% is correct. With switch, it would be:
So that looks wrong to me. |
@ lecy, I thought so as well that they look off. In fact probability table for all my games (with five doors and all three with ten doors) is making the same mistake. Probability for "Stay" is right but "Switch" is wrong. I have checked codes. Not sure what can I be missing. Also curious to see if anyone else encountered the same issue. |
@lecy I've run into a rather odd problem with my code where my outcome.stay does not work, but my outcome.switch runs fine. The codes for both are identical. The only think I'm noticing different is that the little eraser-like symbol next to the code for outcome.switch is pink while the one for outcome.stay is orange: is there a reason for this difference? |
I found this link that indicates that orange is for context while the pink is for vectors. It seems that my code doesn't like to have two different determine_winner that do different things, so I've made a determine_winner1 and determine_winner2 and now the code works EDIT: Here's the link: https://support.rstudio.com/hc/en-us/articles/205273297-Code-Completion |
Okay, I'm a bit confused on what I'm doing wrong to produce the table. I get a long list of results, but for some reason, every time 'stay' wins and switch 'loses':
I'm not sure why this is occurring? My results total is 20,000 observations of the 2 variables. |
This is my data table and probability table for 5 doors ( 3 goats, 2 cars) strategy LOSE WIN
stay 6046 3954
switch 6148 3852
outcome
strategy LOSE WIN
stay 0.60 0.40
switch 0.61 0.39 Row wise total for strategies are adding upto 10,000 but column wise total are not adding up to 10,000. It is the similar problem for other three games with 10 doors. |
I've noticed when I run play_game() on its own, the results never change and I'm not sure why this is happening. It changes if I run the entire .rmd file, but not within the function. Is there a step that I'm overlooking that makes the function change on its own? |
@sunaynagoel OK I found the issue. Dumb mistake on my part! And a nice review of logical statements. To find one door from a set you can write: You cannot, however, compare two vectors: The correct syntax is: So the switch case was broken in change_door(): change_door <- function( stay=T, opened.doors, a.pick )
{
doors <- build_doors()
if( stay )
{
final.pick <- a.pick
}
if( ! stay )
{
# OLD LINE - THIS IS INCORRECT
# available.doors <- doors[ doors != opened.doors & doors != a.pick ]
# THIS IS CORRECT
available.doors <- doors[ ! ( doors %in% opened.doors | doors == a.pick ) ]
final.pick <- sample( available.doors, size=1 )
}
return( final.pick ) # number between 1 and 5
} Once I changed that I got the right solutions as well. |
You play the game 10,000 times, but each time you record outcomes for two strategies. So there are 20,000 outcomes total in the table. The row sums are meaningful (each game of 10,000 is split between wins and losses). The column sums are not meaningful. |
@castower That is odd. Can you send me your RMD file by email? |
@lecy. I get the same result even after I change the code. Is this right ?
strategy LOSE WIN my initial code was
|
I have seen a problem a couple of times now regarding the order of arguments and values in functions. This is subtle, but really important. When we define function, we do so as follows (using an example with one argument with default provided and another without): f.name <- function( arg.a, arg.b = value.b )
{
# only use arg.a and arg.b here
# never reference as value.a or value.b
}
# calling function:
f.name( arg.a=value.a, arg.b=value.b )
# we are assigning values to arguments
f.name( arg.a <- value.a, arg.b <- value.b ) You need to be very careful to (1) only use the argument name ("arg.a") inside of functions, never reference the value with the temp name "value.a". door1 <- select_door()
open_goat_door( a.pick=door1, ... ) The argument a.pick here stores the value so it can be referenced inside of the function. You never want to use door1 inside the function because the next user might call it something different. open_goat_door <- function( a.pick )
{
doors <- 1:3
available.doors <- doors [ - door1 ] # not using arg name!
# available.doors <- doors [ - a.pick ] # should be this
final.pick <- sample( available.doors, size=1 )
return( final.pick )
}
# this won't work now because we don't know what door1 means
initial.pick <- select_door()
open_goat_door( a.pick=initial.pick, ... ) |
@sunaynagoel Your alternative solution looks fine for the change_door() function: # MY SOLUTION
if( ! stay )
{
available.doors <- doors[ ! ( doors %in% opened.doors | doors == a.pick ) ]
final.pick <- sample( available.doors, size=1 )
}
# YOUR SOLUTION
if( ! stay )
{
keep.these.doors<- c(-opened.doors, -a.pick)
available.doors <- doors [keep.these.doors ]
final.pick <- sample( available.doors, size=1 )
}
# CHECKS OUT
> doors <- 1:5
> a.pick <- 2
> opened.doors <- c(1,3)
>
> drop.these.doors <- c( -opened.doors, -a.pick )
> drop.these.doors
[1] -1 -3 -2
> doors[ drop.these.doors ] # available doors
[1] 4 5
>
> drop.these.doors <- c( opened.doors, a.pick )
> drop.these.doors
[1] 1 3 2
> doors[ - drop.these.doors ] # available doors
[1] 4 5 So it must be something else in your code. I am using the solution game steps 1-5 that I gave you for the 3 goats and 2 cars game. Here is what I get: play_game <- function( )
{
new.game <- create_game()
first.pick <- select_door()
opened.door <- open_doors( new.game, first.pick )
final.pick.stay <- change_door( stay=T, opened.door, first.pick )
final.pick.switch <- change_door( stay=F, opened.door, first.pick )
outcome.stay <- determine_winner( final.pick.stay, new.game )
outcome.switch <- determine_winner( final.pick.switch, new.game )
strategy <- c("stay","switch")
outcome <- c(outcome.stay,outcome.switch)
game.results <- data.frame( strategy, outcome,
stringsAsFactors=F )
return( game.results )
}
play_game()
results.df <- NULL # collector
for( i in 1:10000 ) # iterator
{
game.outcome <- play_game()
# binding step
results.df <- rbind( results.df, game.outcome )
}
# library( dplyr )
> table( results.df ) %>%
+ prop.table( margin=1 ) %>% # row proportions
+ round( 2 )
outcome
strategy LOSE WIN
stay 0.60 0.40
switch 0.70 0.30 |
Thank you. I figure out. At one point I was using "door" instead of "doors" so it was picking up variable from my earlier code of LAB 01. Thank you. |
Thanks so much! This helped me understand! @castower |
I am trying to solve question number 2 and I am wondering what I am doing wrong. I thought that if i used the below code that it would get me the correct proportion but I am getting an error.
|
@jmacost5 That loop looks fine, so it has to be a problem with the game code. This is the 10 doors game? What is your game set-up function? |
This is the error I get |
|
@jmacost5 That sounds correct. Please check the solutions for the create_game() function specific to the 10 doors game: build_doors <- function( n ){ return( 1:n ) }
create_game <- function( num.goats, num.cars ) # <- NEW ARGUMENTS
{
a.game <- sample( x=rep( c("goat","car"), c(num.goats,num.cars) ),
size=(num.goats+num.cars), replace=F )
return( a.game )
} And this is the steps of the play_game() function without being wrapped inside of a function: num.goats <- 7
num.cars <- 3
this.game <- create_game( num.goats, num.cars )
my.initial.pick <- select_door( game=this.game )
opened.door <- open_goat_door( this.game, my.initial.pick )
# save results for both strategies for the game
my.final.pick.stay <- change_door( stay=T, game=this.game,
opened.door=opened.door, a.pick=my.initial.pick )
my.final.pick.switch <- change_door( stay=F, game=this.game,
opened.door=opened.door, a.pick=my.initial.pick )
game.outcome.stay <- determine_winner( final.pick=my.final.pick.stay, game=this.game )
game.outcome.switch <- determine_winner( final.pick=my.final.pick.switch, game=this.game ) Note that create_game() requires you to specify 2 new parameters - number of goats and number of cars. There are no default values set. Also note when creating the play_game() function you should not hard-code goat and car numbers into the function: play_game <- function ()
{
num.goats <- 7
num.cars <- 3
this.game <- create_game( num.goats, num.cars )
...
} Because then you can't test the different scenarios for the assignment. You will want to convert these parameters into new arguments: play_game <- function ( num.goats=3, num.cars=2 ) # with defaults
{
this.game <- create_game( num.goats, num.cars )
...
} Does that make sense? |
I am thinking you would want me to put this into the play code? as so play_game <- function(num.goats=7, num.cars=3)
{
this.game <- create_game( num.goats, num.cars )
new.game <- create_game()
first.pick <- select_door()
opened.door <- open_goat_door( new.game, first.pick )
final.pick.stay <- change_door( stay=T, opened.door, first.pick )
final.pick.switch <- change_door( stay=F, opened.door, first.pick )
outcome.stay <- determine_winner( final.pick.stay, new.game )
outcome.switch <- determine_winner( final.pick.switch, new.game )
# game.results <- bundle the results
# return( <<< game.results >>> )
strategy <- c("stay","switch")
outcome <- c(outcome.stay,outcome.switch)
game.results <- data.frame( strategy, outcome,
stringsAsFactors=F )
return( game.results )
}
play_game() |
@jmacost5 Correct. Note that when you include default arguments, you can still override them when calling functions. So in your simulation code you can use: play_game <- function(num.goats=7, num.cars=3)
{
...
}
play_game() # defaults to 7 goats 3 cars
play_game( num.goats=5, num.cars=5 ) # changing game settings |
I am still getting an error, here is the whole code
Error in sample(x = rep(c("goat", "car"), c(num.goats, num.cars)), size = (num.goats + : argument "num.goats" is missing, with no default |
@lecy Link for submitting Lab 02 does not seem to be working for me. |
@sunaynagoel Should be working now. |
@jmacost5 Pay attention to how the functions changed between Part I and Part II. For Part I the game size was static (always 3 goats and 2 cars), so you can hard-code that parameter into the functions. For Part II it is no longer static, so some of the functions need explicit information about the current game to work. For example: # PART I
create_game <- function( )
# PART II
create_game <- function( num.goats, num.cars ) You need to make sure your play_game() function is passing all of the required variables to arguments properly: play_game <- function(num.goats=7, num.cars=3)
{
this.game <- create_game(num.goats, num.cars )
new.game <- create_game()
first.pick <- select_door()
opened.door <- open_goat_door( new.game, first.pick )
final.pick.stay <- change_door( stay=T, opened.door, first.pick )
final.pick.switch <- change_door( stay=F, opened.door, first.pick )
outcome.stay <- determine_winner( final.pick.stay, new.game )
outcome.switch <- determine_winner( final.pick.switch, new.game )
# game.results <- bundle the results
# return( <<< game.results >>> )
strategy <- c("stay","switch")
outcome <- c(outcome.stay,outcome.switch)
game.results <- data.frame( strategy, outcome,
stringsAsFactors=F )
return( game.results )
} ALSO note that you have two build_doors() and two create_games(). |
Hello all, I'm currently working on the final challenge question. To clarify, do we still need to create a table of the outcomes of 10,000 games too? It seems my metadata now makes multiple tables appear for each version of the game. |
@castower That is correct. What do you mean by multiple versions? |
I guess I am missing where I defined game in the code I just cannot find out where I missed it. Error in build_doors(n = length(game)) : argument "game" is missing, with no default |
@jmacost5 You are repeating a bunch of functions like create_game(), which might be the problem. Note the solutions from last week: select_door <- function( game )
{
...
}
play_game <- function(num.goats=7, num.cars=3)
{
new.game <- create_game( num.goats, num.cars )
first.pick <- select_door( game=new.game )
...
} |
I tried to get rid of all the repeats. Am I not suppose to be putting the code on top that is above the "play_game <- function(num.goats=7, num.cars=3)"
|
@jmacost5 These were the repeats in play_game(): play_game <- function(num.goats=7, num.cars=3)
{
this.game <- create_game(num.goats, num.cars )
new.game <- create_game() Your problem is that you are not sending any game to select_door(): first.pick <- select_door( game ) # game not defined anywhere: It should be: play_game <- function(num.goats=7, num.cars=3)
{
new.game <- create_game( num.goats, num.cars )
first.pick <- select_door( game=new.game ) # using the new game
... |
I think I got my code to work but I am not sure if I am getting the right answer or understanding the concept that you said previously about " play_game( num.goats=5, num.cars=5 ) # changing game settings" play_game <- function(num.goats=7, num.cars=3)
{
this.game <- create_game(num.goats, num.cars )
new.game <- create_game()
my.initial.pick <- select_door( game=this.game )
opened.door <- open_goat_door( this.game, my.initial.pick )
# save results for both strategies for the game
my.final.pick.stay <- change_door( stay=T, game=this.game,
opened.door=opened.door, a.pick=my.initial.pick )
my.final.pick.switch <- change_door( stay=F, game=this.game,
opened.door=opened.door, a.pick=my.initial.pick )
outcome.stay <- determine_winner( final.pick=my.final.pick.stay, game=this.game )
outcome.switch <- determine_winner( final.pick=my.final.pick.switch, game=this.game )
# game.results <- bundle the results
# return( <<< game.results >>> )
strategy <- c("stay","switch")
outcome <- c(outcome.stay,outcome.switch)
game.results <- data.frame( strategy, outcome,
stringsAsFactors=F )
return( game.results )
}
results.df <- NULL # collector
for( i in 1:10000 ) # iterator
{
game.outcome <- play_game()
# binding step
results.df <- rbind( results.df, game.outcome )
}
table( results.df )
play_game(num.goats=8, num.cars=2)
results.df <- NULL # collector
for( i in 1:10000 ) # iterator
{
game.outcome <- play_game()
# binding step
results.df <- rbind( results.df, game.outcome )
}
table( results.df )
play_game(num.goats=9, num.cars=1)
results.df <- NULL # collector
for( i in 1:10000 ) # iterator
{
game.outcome <- play_game()
# binding step
results.df <- rbind( results.df, game.outcome )
}
table( results.df ) These were the answers respectively |
@lecy for just one game I get the following output (I'm going to add the other variables later, I'm just including game set up and initial contestant while I problem-solve):
However, when I run it through the loop, I get this:
This output of the loop doesn't seem to be telling me anything. |
@jmacost5 Those answers are right for th 7,3 case. You just need to add your arguments to the play_game() function inside of the loop, otherwise for the 10,000 trials it is just using the default game set-up. results.df <- NULL # collector
for( i in 1:10000 ) # iterator
{
game.outcome <- play_game()
# binding step
results.df <- rbind( results.df, game.outcome )
}
table( results.df )
play_game(num.goats=9, num.cars=1) |
@castower send me your file via email? |
@lecy I sent it. Thank you! |
Hi, Jaesa and I are coming up with an issue with the data results. All of our code is running through without errors but we are getting STAY as consistently the dominant strategy. Anyone else having the same issue? |
@meliapetersen which part of the code? I did get STAY as the superior strategy for one of the outcomes, but all the rest of my results found SWITCH to be superior. |
@castower It is every single one that does it. The original simulation as well as the new simulations for part 2. -- Each time we run it there is a different result as well. |
@meliapetersen do you get results for SWITCH too and STAY is just superior? Or do you get 0s? At one point I would get 100% (1) win for SWITCH and 100% (1) lose for STAY and it turned out that the way I'd coded my variables was causing the loop to keep forcing the same value over and over. The code didn't have any errors, but the output was wrong because it was duplicating one game 10,000 times. |
@meliapetersen I just re-sent the most up-to-date solutions for functions from Lab-01 via Canvas. I would start there and make sure you are using the current code, then try to wrap them into the play_game() function. There is a lot of subtlety to the logic in some of the functions where you are using criteria to select doors. You usually need to review the logic of the pseudo-code to make sure your steps are correct. The next part is translating from logic to syntax, which is another way errors can creep in. For example: x %in% c("a","b") # correct way to do multiple comparisons at once
x == c("a","b") # this is incorrect - will only use "a" Or a very common one with compound statements: # eliminate case A and case B
! ( x == "case A" | x == "case B" ) In plain English we say, we only want the cases where A and B are both true (intersection, so we use CaseA & CaseB. We also say, I need to drop all cars AND the current selection before opening a door. But in logical statement terms this is translated to CaseA OR CaseB. If the functions are working fine, send your play_game() code! |
@lecy Our functions are working fine, but we still keep getting inconsistent outputs for switch and stay. Our play_games() code looks like this:
|
@JaesaR I can see one problem which I know will cause some errors. Hopefully it is your only one. You are repeating the create_game( ) function, then using one version of the game for some steps, and another version for other steps. This could lead to conflicts (though I am not sure if yours do here). Other that that, this step looks good. What's your simulation loop look like? play_game <- function( num.goats=7, num.cars=3 )
{
# this.game <- create_game(num.goats, num.cars )
new.game <- create_game( num.goats, num.cars )
# first.pick <- select_door(game=this.game) # changed this.game to new.game
first.pick <- select_door( game=new.game )
opened.door <- open_goat_door( new.game, first.pick )
final.pick.stay <- change_door( stay=T, opened.door=opened.door, a.pick=first.pick )
final.pick.switch <- change_door( stay=F, opened.door=opened.door, a.pick=first.pick )
outcome.stay <- determine_winner( final.pick.stay, new.game )
outcome.switch <- determine_winner( final.pick.switch, new.game )
strategy <- c( "stay","switch" )
outcome <- c( outcome.stay,outcome.switch )
game.results <- data.frame( strategy, outcome,
stringsAsFactors=F )
return( game.results )
}
play_game() |
@lecy Great, thanks! That helped. |
@JaesaR They are opportunities, but not required. |
After testing the simulation for LAB 01 with my codes and provided codes, I was able to set up codes for new game (LAB-02 #1). But when I got to test the game function I get error
"longer object length is not a multiple of shorter object length" and that error further creates problem in binding the table. I think it has to do with vector dimension and after trying to troubleshoot with help of google, I am here for help. The problem is with "a.pick". Here are the codes and error.
Error
longer object length is not a multiple of shorter object length
The text was updated successfully, but these errors were encountered: