DS4PS / cpp-527-spr-2020

Course shell for CPP 527 Foundations of Data Science II for Spring 2020.
http://ds4ps.org/cpp-527-spr-2020/
0 stars 1 forks source link

LAB 02 #4

Open sunaynagoel opened 4 years ago

sunaynagoel commented 4 years ago

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.

this.game <- create_game()
my.initial.pick <- select_door()
opened.doors <- open_doors( this.game, my.initial.pick )

my.final.pick.stay <- change_door( stay=T, opened.doors=opened.doors, a.pick=my.initial.pick )
my.final.pick.switch <- change_door( stay=F, opened.doors=opened.doors, 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 )

Error longer object length is not a multiple of shorter object length

lecy commented 4 years ago

@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.

lecy commented 4 years ago

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
}
sunaynagoel commented 4 years ago

@lecy Thank you for the update. Even after updating the code at my end it keeps giving the same error.

castower commented 4 years ago

@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

sunaynagoel commented 4 years ago

@lecy After changing the way we collected data for available.door my error went away. I changed the provided code

{
   doors <- build_doors()

   if( stay )
   {
     final.pick <- a.pick
   }
   if( ! stay )
   {
     available.doors <- doors[ doors != opened.doors & doors != a.pick ]
     final.pick  <- sample( available.doors, size=1 ) 
   }

   return( final.pick )  
}

to

{
   doors <- build_doors()

   if( stay )
   {
     final.pick <- a.pick
   }
   if( ! stay )
   {
     keep.these.doors <- c(-opened.doors, -a.pick)
     available.doors <- doors [keep.these.doors ]
     final.pick  <- sample( available.doors, size=1 ) 
   }

   return( final.pick )  
}

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.

castower commented 4 years ago

@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 Nevermind, finally got it working!

lecy commented 4 years ago

@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 !!!

sunaynagoel commented 4 years ago

Does this outcome look right for the 5 doors game (3 goats and 2 cars)? outcome strategy LOSE WIN stay 0.59 0.41 switch 0.60 0.40

lecy commented 4 years ago

With stay, you have a 2 in 5 shot of guessing correctly first time. So 40% is correct.

With switch, it would be:

prob guess car first * prob guess car second + 
prob guess goat first * prob guess car second
(0.4)(0) + (0.6)(0.5) = 30%

So that looks wrong to me.

sunaynagoel commented 4 years ago

With stay, you have a 2 in 5 shot of guessing correctly first time. So 40% is correct.

With switch, it would be:

prob guess car first * prob guess car second + 
prob guess goat first * prob guess car second
(0.4)(0) + (0.6)(0.5) = 30%

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.

castower commented 4 years ago

@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:

Screen Shot 2020-01-28 at 2 34 24 PM

is there a reason for this difference?

castower commented 4 years ago

@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:

Screen Shot 2020-01-28 at 2 34 24 PM

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

castower commented 4 years ago

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':

outcome
strategy LOSE WIN
  stay      0   1
  switch    1   0

I'm not sure why this is occurring? My results total is 20,000 observations of the 2 variables.

sunaynagoel commented 4 years ago

This is my data table and probability table for 5 doors ( 3 goats, 2 cars) outcome

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.

castower commented 4 years ago

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?

lecy commented 4 years ago

@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: doors == 5

You cannot, however, compare two vectors: doors == c(2,5)

The correct syntax is: doors %in% c(2,5)

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.

lecy commented 4 years ago

This is my data table and probability table for 5 doors ( 3 goats, 2 cars) outcome

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.

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.

lecy commented 4 years ago

@castower That is odd. Can you send me your RMD file by email?

castower commented 4 years ago

@castower That is odd. Can you send me your RMD file by email?

Yes, I just sent it. Thank you! @lecy

sunaynagoel commented 4 years ago

@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: doors == 5

You cannot, however, compare two vectors: doors == c(2,5)

The correct syntax is: doors %in% c(2,5)

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.

@Lecy. I get the same result even after I change the code. Is this right ?

outcome

strategy LOSE WIN stay 6006 3994 switch 5990 4010 outcome strategy LOSE WIN stay 0.6 0.4 switch 0.6 0.4

my initial code was

{
   doors <- build_doors(  )

   if( stay )
   {
     final.pick <- a.pick
   }
   if( ! stay )
   {
    keep.these.doors<- c(-opened.doors, -a.pick)
      available.doors <- doors [keep.these.doors ]
    final.pick  <- sample( available.doors, size=1 ) 
   }
   return( final.pick ) 
lecy commented 4 years ago

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, ... )
lecy commented 4 years ago

@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
sunaynagoel commented 4 years ago

@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.

castower commented 4 years ago

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, ... )

Thanks so much! This helped me understand! @castower

jmacost5 commented 4 years ago

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.


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 ) 
lecy commented 4 years ago

@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?

jmacost5 commented 4 years ago

@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? Yes, This is the ten door function game, 7 goats 3 cars, I wanted to understand what is wrong with the play_game code I am using

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 )

This is the error I get Error in sample(x = rep(c("goat", "car"), c(num.goats, num.cars)), size = (num.goats + : argument "num.goats" is missing, with no default

jmacost5 commented 4 years ago

@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? I guess my question is am I missing the num.goat argument in the play_game or in the original code? The original code is working but the other is not.

lecy commented 4 years ago

@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?

jmacost5 commented 4 years ago

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()
lecy commented 4 years ago

@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
jmacost5 commented 4 years ago

@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


build_doors <- function( n ){ return( 1:n ) }

create_game <- function( num.goats, num.cars )  # <- NEW ARGUMENTS
{

}

select_door <- function( game )
{

}

build_doors <- function( n ){ return( 1:n ) }

create_game <- function( num.goats, num.cars )
{

}

select_door <- function( game )
{

}

open_goat_door <- function( game, a.pick )
{

}

change_door <- function( stay=T, game, opened.door, a.pick )
{

}

determine_winner <- function( final.pick, game )
{

}
 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()

results.df <- NULL   # collector

for( i in 1:10000 )  # iterator
{
  game.outcome <- play_game()
  results.df <- rbind( results.df, game.outcome )
}

table( results.df )

Error in sample(x = rep(c("goat", "car"), c(num.goats, num.cars)), size = (num.goats + : argument "num.goats" is missing, with no default

sunaynagoel commented 4 years ago

@lecy Link for submitting Lab 02 does not seem to be working for me.

lecy commented 4 years ago

@sunaynagoel Should be working now.

lecy commented 4 years ago

@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().

castower commented 4 years ago

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.

lecy commented 4 years ago

@castower That is correct. What do you mean by multiple versions?

jmacost5 commented 4 years ago

@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().

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

lecy commented 4 years ago

@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 )
 ...
}
jmacost5 commented 4 years ago

@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)"

lecy commented 4 years ago

@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
  ... 
jmacost5 commented 4 years ago

@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 outcome strategy LOSE WIN stay 6982 3018 switch 6632 3368 outcome strategy LOSE WIN stay 7001 2999 switch 6601 3399 outcome strategy LOSE WIN stay 7069 2931 switch 6610 3390

castower commented 4 years ago

@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):

strategy outcome game.set.up initial.contestant  
stay LOSE goat car goat 3  
switch WIN goat car goat 3

However, when I run it through the loop, I get this:

, , game.set.up = car goat goat, initial.contestant = 3

        outcome
strategy LOSE  WIN
  stay   0.11 0.00
  switch 0.00 0.11

, , game.set.up = goat goat car, initial.contestant = 3

        outcome
strategy LOSE  WIN
  stay   0.00 0.11
  switch 0.11 0.00
, , game.set.up = goat car goat, initial.contestant = 3

        outcome
strategy LOSE  WIN
  stay   0.11 0.00
  switch 0.00 0.11

, , game.set.up = car goat goat, initial.contestant = 1

        outcome
strategy LOSE  WIN
  stay   0.00 0.11
  switch 0.11 0.00

, , game.set.up = goat goat car, initial.contestant = 1

        outcome
strategy LOSE  WIN
  stay   0.11 0.00
  switch 0.00 0.11
, , game.set.up = goat car goat, initial.contestant = 1

        outcome
strategy LOSE  WIN
  stay   0.11 0.00
  switch 0.00 0.11

, , game.set.up = car goat goat, initial.contestant = 2

        outcome
strategy LOSE  WIN
  stay   0.12 0.00
  switch 0.00 0.12

, , game.set.up = goat goat car, initial.contestant = 2

        outcome
strategy LOSE  WIN
  stay   0.11 0.00
  switch 0.00 0.11
, , game.set.up = goat car goat, initial.contestant = 2

        outcome
strategy LOSE  WIN
  stay   0.00 0.11
  switch 0.11 0.00

This output of the loop doesn't seem to be telling me anything.

lecy commented 4 years ago

@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)
lecy commented 4 years ago

@castower send me your file via email?

castower commented 4 years ago

@lecy I sent it. Thank you!

meliapetersen commented 4 years ago

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?

castower commented 4 years ago

@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.

meliapetersen commented 4 years ago

@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.

castower commented 4 years ago

@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.