# Hand on Programming with R
# By Garrett Grolemund
setwd("C:\\Users\\Luis\\Desktop\\HandOnProgramming_R")
# Objects, R lets you save data by storing it inside an R objec
die <- 1:6
die
## [1] 1 2 3 4 5 6
# You can do inner multiplication with
# the %*% operator and
die%*%die
##      [,1]
## [1,]   91
# outer multiplication with the %o% operator:
die%o%die
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    2    3    4    5    6
## [2,]    2    4    6    8   10   12
## [3,]    3    6    9   12   15   18
## [4,]    4    8   12   16   20   24
## [5,]    5   10   15   20   25   30
## [6,]    6   12   18   24   30   36
# Functions, R comes with many functions 
# that you can use to do sophisticated 
# tasks like random sampling
mean(die)
## [1] 3.5
round(mean(die))
## [1] 4
sample(x=die,size = 1)
## [1] 3
sample(x=die,size = 2)
## [1] 2 1
sample(x=die,size = 6)
## [1] 4 1 6 3 2 5
sample(die,size = 3)
## [1] 3 1 5
round(pi,digits = 5)
## [1] 3.14159
args(round)
## function (x, digits = 0) 
## NULL
round(pi,digits =1)
## [1] 3.1
# Sample with Replacement
sample(die,size=2,replace = TRUE)
## [1] 4 4
dice <- sample(die,size = 2,replace = TRUE)
dice
## [1] 2 1
sum(dice)
## [1] 3
dice
## [1] 2 1
dice
## [1] 2 1
dice
## [1] 2 1
# Writing Your Own Functions
roll <- function(){
  die <- 1:6
  dice <- sample(die,size = 2,replace = TRUE)
  sum(dice)
}
roll()
## [1] 10
# Arguments, You can supply bones when
# you call roll2 if you make bones
roll2 <-function(bones){
  dice <- sample(bones,size = 2,replace = TRUE)
  sum(dice)
}
roll2(2)
## [1] 3
roll2(4)
## [1] 3
roll2(1:6)
## [1] 11
roll()
## [1] 12
roll2(1:10)
## [1] 15
# You can prevent this error by giving 
# the bones argument a default value. 
# To do this, set bones equal to a 
# value when you define roll3:
roll3 <-function(bones=1:6){
  dice <- sample(bones,size = 2,replace = TRUE)
  sum(dice)
}
roll3()
## [1] 7
# library
library(ggplot2)
# Let's take a look at a histogram to see
# if this makes sense. qplot will make a
# histogram whenever you give it only 
# one vector to plot.
x3 <- c(0,1,1,2,2,2,3,3,4)
qplot(x3,binwidth=1)

# If you roll your dice many times and 
# plot the results with qplot, the histogram 
# will show you how often each sum appeared.
# The sums that occurred most often will 
# have the highest bars
replicate(10,roll())
##  [1]  6  4  6  9  7  5  8  8  4 11
# Patterns of long run frequencies will only
# appear over the long run. So let's simulate
# 10,000 dice rolls and plot the results
rolls <-replicate(1000,roll())
qplot(rolls,binwidth=1)

#help(sample)
#?sample()
# To weight your dice, you need to add
# a prob argument with a vector of weights
# to sample, like this:
roll4 <- function(){
  die <- 1:6
  dice <-sample(die,size = 2,replace = TRUE,
                prob = c(1/8,1/8,1/8,1/8,1/8,3/8))
  sum(dice)
}
roll4()
## [1] 3
rolls <- replicate(10000,roll4())
qplot(rolls,binwidth=1)

# Part II. Project 2: Playing Cards
# This project-which spans the next four 
# chapters-will teach you how to store,
# retrieve, and change data values in your
# computer's memory.
# To keep the project simple, I've divided it
# into four tasks. Each task will teach you
# a new skill for managing data with R:
# Chapter 3. R Objects
# There is more than one way to build this matrix,
# but in every case, you will need to start by
# making a character vector with 10 values.
# If you start with the following character vector,
# you can turn it into a matrix with any of 
# the following three commands:
hand1 <- c("ace","king","queen","jack",
           "ten","spades","spades",
           "spades","spades","spades")
matrix(hand1,nrow = 5)
##      [,1]    [,2]    
## [1,] "ace"   "spades"
## [2,] "king"  "spades"
## [3,] "queen" "spades"
## [4,] "jack"  "spades"
## [5,] "ten"   "spades"
matrix(hand1,ncol=2)
##      [,1]    [,2]    
## [1,] "ace"   "spades"
## [2,] "king"  "spades"
## [3,] "queen" "spades"
## [4,] "jack"  "spades"
## [5,] "ten"   "spades"
dim(hand1) <- c(5,2)
hand2 <- c("ace","spades","king","spades","queen","spades","jack","spades",
           "ten","spades")
matrix(hand2,nrow = 5,byrow = TRUE)
##      [,1]    [,2]    
## [1,] "ace"   "spades"
## [2,] "king"  "spades"
## [3,] "queen" "spades"
## [4,] "jack"  "spades"
## [5,] "ten"   "spades"
matrix(hand2,ncol = 2,byrow = TRUE)
##      [,1]    [,2]    
## [1,] "ace"   "spades"
## [2,] "king"  "spades"
## [3,] "queen" "spades"
## [4,] "jack"  "spades"
## [5,] "ten"   "spades"
class(hand2)
## [1] "character"
# Dates and Times
now <- Sys.time()
now
## [1] "2016-02-18 07:23:45 VET"
# The time looks like a character string
# when you display it, but its data type
# is actually "double", and its class 
# is "POSIXct" "POSIXt" (it has two classes):
class(now)
## [1] "POSIXct" "POSIXt"
# Loading Data
# You can load the deck data frame from 
# the file deck.csv.
deck <- read.csv("C:\\Users\\Luis\\Desktop\\HandOnProgramming_R\\deck.csv",
                 header = TRUE,stringsAsFactors = FALSE)
deck[1:2,]
##    face   suit value
## 1  king spades    13
## 2 queen spades    12
x <- deck[1:2,1:2]
class(x)
## [1] "data.frame"
y <- deck[1:2,1]
y
## [1] "king"  "queen"
class(y)
## [1] "character"
y <- deck[1:2,1,drop=FALSE]
y
##    face
## 1  king
## 2 queen
class(y)
## [1] "data.frame"
deck[-1,1]
##  [1] "queen" "jack"  "ten"   "nine"  "eight" "seven" "six"   "five" 
##  [9] "four"  "three" "two"   "ace"   "king"  "queen" "jack"  "ten"  
## [17] "nine"  "eight" "seven" "six"   "five"  "four"  "three" "two"  
## [25] "ace"   "king"  "queen" "jack"  "ten"   "nine"  "eight" "seven"
## [33] "six"   "five"  "four"  "three" "two"   "ace"   "king"  "queen"
## [41] "jack"  "ten"   "nine"  "eight" "seven" "six"   "five"  "four" 
## [49] "three" "two"   "ace"
# Chapter 4. R Notation
# EXERCISE
# Complete the following code to make
# a function that returns the first 
# row of a data frame:
# deal <- function(cards) {
#   # ?
# }
# answer:
deal <- function(cards){
  cards[1,]
}
deal(deck)#The function does exactly what
##   face   suit value
## 1 king spades    13
# you want: it deals the top card from 
# your data set deal always returns the
# king of spades because deck doesn't know 
# that we've dealt the card away
# Shuffle the Deck
# This may sound silly, but start by extracting
# every row in your data frame:
deck2 <- deck[1:52, ]
head(deck2)
##    face   suit value
## 1  king spades    13
## 2 queen spades    12
## 3  jack spades    11
## 4   ten spades    10
## 5  nine spades     9
## 6 eight spades     8
# What do you get? A new data frame whose order
# hasn't changed at all. What if you asked R
# to extract the rows in a different order? 
# For example, you could ask for row 2,
# then row 1, and then the rest of the cards:
deck3 <- deck[c(2, 1, 3:52), ]
head(deck3)
##    face   suit value
## 2 queen spades    12
## 1  king spades    13
## 3  jack spades    11
## 4   ten spades    10
## 5  nine spades     9
## 6 eight spades     8
# R complies. You'll get all the rows back,
# and they'll come in the order you ask for
# them. If you want the rows to come in a 
# random order, then you need to sort the 
# integers from 1 to 52 into a random order
# and use the results as a row index. 
# How could you generate such a random 
# collection of integers? With our friendly
# neighborhood sample function:
random <- sample(1:52, size = 52)
random #Now the new set is truly shuffled.
##  [1] 16  6 22  7 13 20 36 30  9 52 19 29 33  2 24 26 14 39 31 12 42 41 43
## [24]  8 50 48 44 40 32 11  3 38 34 17 51 25 45 21 37 23 47  4 15 18 28  1
## [47]  5 10 49 27 35 46
# You'll be finished once you wrap these
# steps into a function.
shuffle <- function(cards){
  random <- sample(1:52,size = 52)
  cards[random,]
}
shuffle(deck)
##     face     suit value
## 4    ten   spades    10
## 2  queen   spades    12
## 31  nine diamonds     9
## 25   two    clubs     2
## 52   ace   hearts     1
## 51   two   hearts     2
## 26   ace    clubs     1
## 20 seven    clubs     7
## 45 eight   hearts     8
## 19 eight    clubs     8
## 9   five   spades     5
## 40  king   hearts    13
## 47   six   hearts     6
## 28 queen diamonds    12
## 30   ten diamonds    10
## 48  five   hearts     5
## 3   jack   spades    11
## 27  king diamonds    13
## 32 eight diamonds     8
## 34   six diamonds     6
## 7  seven   spades     7
## 24 three    clubs     3
## 16  jack    clubs    11
## 36  four diamonds     4
## 11 three   spades     3
## 50 three   hearts     3
## 35  five diamonds     5
## 17   ten    clubs    10
## 46 seven   hearts     7
## 43   ten   hearts    10
## 49  four   hearts     4
## 23  four    clubs     4
## 33 seven diamonds     7
## 21   six    clubs     6
## 18  nine    clubs     9
## 37 three diamonds     3
## 14  king    clubs    13
## 15 queen    clubs    12
## 5   nine   spades     9
## 39   ace diamonds     1
## 1   king   spades    13
## 44  nine   hearts     9
## 22  five    clubs     5
## 10  four   spades     4
## 13   ace   spades     1
## 8    six   spades     6
## 29  jack diamonds    11
## 12   two   spades     2
## 42  jack   hearts    11
## 41 queen   hearts    12
## 38   two diamonds     2
## 6  eight   spades     8
deck2 <-shuffle(deck)
deal(deck2)
##    face     suit value
## 38  two diamonds     2
deck_2 <- deck
# In the game of war, aces are king 
# (figuratively speaking). They receive
# the highest value of all the cards,
# which would be something like 14. 
# Every other card gets the value 
# that it already has in deck.
# To play war, you just need to change
# the values of your aces from 1 to 14.
# As long as you haven't shuffled your deck,
# you know just where the aces are. 
# They appear every 13 cards. Hence, 
# you can describe them with R's notation system:
deck_2[c(13,26,39,52),]
##    face     suit value
## 13  ace   spades     1
## 26  ace    clubs     1
## 39  ace diamonds     1
## 52  ace   hearts     1
deck_2$value[c(13,26,39,52)]
## [1] 1 1 1 1
deck_2$value[c(13,26,39,52)] <- 14
deck_2$value
##  [1] 13 12 11 10  9  8  7  6  5  4  3  2 14 13 12 11 10  9  8  7  6  5  4
## [24]  3  2 14 13 12 11 10  9  8  7  6  5  4  3  2 14 13 12 11 10  9  8  7
## [47]  6  5  4  3  2 14
head(deck_2,13)
##     face   suit value
## 1   king spades    13
## 2  queen spades    12
## 3   jack spades    11
## 4    ten spades    10
## 5   nine spades     9
## 6  eight spades     8
## 7  seven spades     7
## 8    six spades     6
## 9   five spades     5
## 10  four spades     4
## 11 three spades     3
## 12   two spades     2
## 13   ace spades    14
# But what if the deck had been shuffled?
# You could look through all the cards and
# note the locations of the aces, but that
# would be tedious. If your data frame were 
# larger, it might be impossible:
deck_3 <- shuffle(deck)
head(deck_3)
##     face     suit value
## 23  four    clubs     4
## 40  king   hearts    13
## 31  nine diamonds     9
## 19 eight    clubs     8
## 29  jack diamonds    11
## 25   two    clubs     2
# Why not ask R to find the aces for you? 
# You can do this with logical subsetting.
# Logical subsetting provides a way to do 
# targeted extraction and modification with R
# objects, a sort of search-and-destroy
# mission inside your own data sets.
deck_2[,1]=="ace"
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [12] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [23] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [34] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
## [45] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
sum(deck_2[,1]=="ace")
## [1] 4
deck_2$face=="ace"
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [12] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [23] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [34] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
## [45] FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE
sum(deck_2=="ace")
## [1] 4
# You can use this method to spot and
# then change the aces in your deck-even 
# if you've shuffled your cards. 
# First, build a logical test that 
# identifies the aces in your shuffled deck:
deck_3$face=="ace"
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
## [12] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [23] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [34] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
## [45] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE
# Then use the test to single out 
# the ace point values. Since the
# test returns a logical vector,
# you can use it as an index:
deck_3$value[deck_3$face=="ace"]
## [1] 1 1 1 1
#Finally, use assignment to change 
#the ace values in deck3:
deck_3$value[deck_3$face == "ace"] <- 14
head(deck_3)
##     face     suit value
## 23  four    clubs     4
## 40  king   hearts    13
## 31  nine diamonds     9
## 19 eight    clubs     8
## 29  jack diamonds    11
## 25   two    clubs     2
# Let's put logical subsetting to use
# with a new game: hearts. In hearts,
# every card has a value of zero:
deck_4 <- deck
deck_4$value <- 0
deck_4
##     face     suit value
## 1   king   spades     0
## 2  queen   spades     0
## 3   jack   spades     0
## 4    ten   spades     0
## 5   nine   spades     0
## 6  eight   spades     0
## 7  seven   spades     0
## 8    six   spades     0
## 9   five   spades     0
## 10  four   spades     0
## 11 three   spades     0
## 12   two   spades     0
## 13   ace   spades     0
## 14  king    clubs     0
## 15 queen    clubs     0
## 16  jack    clubs     0
## 17   ten    clubs     0
## 18  nine    clubs     0
## 19 eight    clubs     0
## 20 seven    clubs     0
## 21   six    clubs     0
## 22  five    clubs     0
## 23  four    clubs     0
## 24 three    clubs     0
## 25   two    clubs     0
## 26   ace    clubs     0
## 27  king diamonds     0
## 28 queen diamonds     0
## 29  jack diamonds     0
## 30   ten diamonds     0
## 31  nine diamonds     0
## 32 eight diamonds     0
## 33 seven diamonds     0
## 34   six diamonds     0
## 35  five diamonds     0
## 36  four diamonds     0
## 37 three diamonds     0
## 38   two diamonds     0
## 39   ace diamonds     0
## 40  king   hearts     0
## 41 queen   hearts     0
## 42  jack   hearts     0
## 43   ten   hearts     0
## 44  nine   hearts     0
## 45 eight   hearts     0
## 46 seven   hearts     0
## 47   six   hearts     0
## 48  five   hearts     0
## 49  four   hearts     0
## 50 three   hearts     0
## 51   two   hearts     0
## 52   ace   hearts     0
# except cards in the suit of 
# hearts and the queen of spades.
# Each card in the suit of hearts
# has a value of 1
deck_4$suit=="hearts"
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [12] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [23] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [34] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
## [45]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
deck_4$value[deck_4$suit=="hearts"]
##  [1] 0 0 0 0 0 0 0 0 0 0 0 0 0
deck_4$value[deck_4$suit=="hearts"] <- 1
deck_4$value[deck_4$suit=="hearts"]
##  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1
queenOfspades <- deck_4$face=="queen"&deck_4$suit=="spades"
deck_4[queenOfspades,]
##    face   suit value
## 2 queen spades     0
deck_4$value[queenOfspades]<- 13
deck_4[queenOfspades,]
##    face   suit value
## 2 queen spades    13
# Your deck is now ready to play hearts.
# Exercises
# Is w positive?
# Is x greater than 10 and less than 20?
# Is object y the word February?
# Is every value in z a day of the week?
 w <- c(-1, 0, 1)
 x <- c(5, 15)
 y <- "February"
 z <- c("Monday", "Tuesday", "Friday")
w > 0
## [1] FALSE FALSE  TRUE
10<x & x<20
## [1] FALSE  TRUE
y=="February"
## [1] TRUE
all(z %in% c("Monday","Tuesday","Wednesday","Thrusday",
             "Friday","Saturday","Sunday"))
## [1] TRUE
# Let's consider one last game, blackjack.
# In blackjack, each number card has 
# a value equal to its face value.
# Each face card (king, queen, or jack)
# has a value of 10. Finally, each ace
# has a value of 11 or 1, depending on
# the final results of the game.
deck_5 <- deck
head(deck_5)
##    face   suit value
## 1  king spades    13
## 2 queen spades    12
## 3  jack spades    11
## 4   ten spades    10
## 5  nine spades     9
## 6 eight spades     8
# You can change the value of the face cards
# in one fell swoop with %in%:
facecard <- deck_5$face %in% c("king","queen","jack")
deck_5$value[facecard] <- 10
deck_5
##     face     suit value
## 1   king   spades    10
## 2  queen   spades    10
## 3   jack   spades    10
## 4    ten   spades    10
## 5   nine   spades     9
## 6  eight   spades     8
## 7  seven   spades     7
## 8    six   spades     6
## 9   five   spades     5
## 10  four   spades     4
## 11 three   spades     3
## 12   two   spades     2
## 13   ace   spades     1
## 14  king    clubs    10
## 15 queen    clubs    10
## 16  jack    clubs    10
## 17   ten    clubs    10
## 18  nine    clubs     9
## 19 eight    clubs     8
## 20 seven    clubs     7
## 21   six    clubs     6
## 22  five    clubs     5
## 23  four    clubs     4
## 24 three    clubs     3
## 25   two    clubs     2
## 26   ace    clubs     1
## 27  king diamonds    10
## 28 queen diamonds    10
## 29  jack diamonds    10
## 30   ten diamonds    10
## 31  nine diamonds     9
## 32 eight diamonds     8
## 33 seven diamonds     7
## 34   six diamonds     6
## 35  five diamonds     5
## 36  four diamonds     4
## 37 three diamonds     3
## 38   two diamonds     2
## 39   ace diamonds     1
## 40  king   hearts    10
## 41 queen   hearts    10
## 42  jack   hearts    10
## 43   ten   hearts    10
## 44  nine   hearts     9
## 45 eight   hearts     8
## 46 seven   hearts     7
## 47   six   hearts     6
## 48  five   hearts     5
## 49  four   hearts     4
## 50 three   hearts     3
## 51   two   hearts     2
## 52   ace   hearts     1
deck_5$value[deck_5$face=="ace"]<- NA
deck_5
##     face     suit value
## 1   king   spades    10
## 2  queen   spades    10
## 3   jack   spades    10
## 4    ten   spades    10
## 5   nine   spades     9
## 6  eight   spades     8
## 7  seven   spades     7
## 8    six   spades     6
## 9   five   spades     5
## 10  four   spades     4
## 11 three   spades     3
## 12   two   spades     2
## 13   ace   spades    NA
## 14  king    clubs    10
## 15 queen    clubs    10
## 16  jack    clubs    10
## 17   ten    clubs    10
## 18  nine    clubs     9
## 19 eight    clubs     8
## 20 seven    clubs     7
## 21   six    clubs     6
## 22  five    clubs     5
## 23  four    clubs     4
## 24 three    clubs     3
## 25   two    clubs     2
## 26   ace    clubs    NA
## 27  king diamonds    10
## 28 queen diamonds    10
## 29  jack diamonds    10
## 30   ten diamonds    10
## 31  nine diamonds     9
## 32 eight diamonds     8
## 33 seven diamonds     7
## 34   six diamonds     6
## 35  five diamonds     5
## 36  four diamonds     4
## 37 three diamonds     3
## 38   two diamonds     2
## 39   ace diamonds    NA
## 40  king   hearts    10
## 41 queen   hearts    10
## 42  jack   hearts    10
## 43   ten   hearts    10
## 44  nine   hearts     9
## 45 eight   hearts     8
## 46 seven   hearts     7
## 47   six   hearts     6
## 48  five   hearts     5
## 49  four   hearts     4
## 50 three   hearts     3
## 51   two   hearts     2
## 52   ace   hearts    NA
# Congratulations. Your deck is now ready 
# for a game of blackjack.Congratulations. 
# Your deck is now ready for a game of blackjack.
library(pryr)
parenvs(all=TRUE)
##    label                            name               
## 1  <environment: R_GlobalEnv>       ""                 
## 2  <environment: package:pryr>      "package:pryr"     
## 3  <environment: package:ggplot2>   "package:ggplot2"  
## 4  <environment: package:stats>     "package:stats"    
## 5  <environment: package:graphics>  "package:graphics" 
## 6  <environment: package:grDevices> "package:grDevices"
## 7  <environment: package:utils>     "package:utils"    
## 8  <environment: package:datasets>  "package:datasets" 
## 9  <environment: package:methods>   "package:methods"  
## 10 <environment: 0x04ec5828>        "Autoloads"        
## 11 <environment: base>              ""                 
## 12 <environment: R_EmptyEnv>        ""
ls(globalenv())
##  [1] "deal"          "deck"          "deck_2"        "deck_3"       
##  [5] "deck_4"        "deck_5"        "deck2"         "deck3"        
##  [9] "dice"          "die"           "facecard"      "hand1"        
## [13] "hand2"         "now"           "queenOfspades" "random"       
## [17] "roll"          "roll2"         "roll3"         "roll4"        
## [21] "rolls"         "shuffle"       "w"             "x"            
## [25] "x3"            "y"             "z"
environment()
## <environment: R_GlobalEnv>
foo <- "take me to your runtime"

show_env <- function(x = foo){
  list(ran.in = environment(),
       parent = parent.env(environment()),
       objects = ls.str(environment()))
}
show_env(1:6)
## $ran.in
## <environment: 0x086ce710>
## 
## $parent
## <environment: R_GlobalEnv>
## 
## $objects
## x :  int [1:6] 1 2 3 4 5 6
x <- c(1:6)
y <- 3
add<- function(){
  exp(x*y)^2
}
add()
## [1] 4.034288e+02 1.627548e+05 6.565997e+07 2.648912e+10 1.068647e+13
## [6] 4.311232e+15
deal <- function(){
  deck[1,]
}
environment(deal)
## <environment: R_GlobalEnv>
deal()
##   face   suit value
## 1 king spades    13
# You know enough R syntax to remove 
# the top card of deck. The following
# code will save a pristine copy of deck
# and then remove the top card:
DECK <- deck
deck <- deck[-1,]
head(deck)
##    face   suit value
## 2 queen spades    12
## 3  jack spades    11
## 4   ten spades    10
## 5  nine spades     9
## 6 eight spades     8
## 7 seven spades     7
deal <- function(){
  card <- deck[-1,]
  deck <-  deck[-1,]
  card
}
deal()
##     face     suit value
## 3   jack   spades    11
## 4    ten   spades    10
## 5   nine   spades     9
## 6  eight   spades     8
## 7  seven   spades     7
## 8    six   spades     6
## 9   five   spades     5
## 10  four   spades     4
## 11 three   spades     3
## 12   two   spades     2
## 13   ace   spades     1
## 14  king    clubs    13
## 15 queen    clubs    12
## 16  jack    clubs    11
## 17   ten    clubs    10
## 18  nine    clubs     9
## 19 eight    clubs     8
## 20 seven    clubs     7
## 21   six    clubs     6
## 22  five    clubs     5
## 23  four    clubs     4
## 24 three    clubs     3
## 25   two    clubs     2
## 26   ace    clubs     1
## 27  king diamonds    13
## 28 queen diamonds    12
## 29  jack diamonds    11
## 30   ten diamonds    10
## 31  nine diamonds     9
## 32 eight diamonds     8
## 33 seven diamonds     7
## 34   six diamonds     6
## 35  five diamonds     5
## 36  four diamonds     4
## 37 three diamonds     3
## 38   two diamonds     2
## 39   ace diamonds     1
## 40  king   hearts    13
## 41 queen   hearts    12
## 42  jack   hearts    11
## 43   ten   hearts    10
## 44  nine   hearts     9
## 45 eight   hearts     8
## 46 seven   hearts     7
## 47   six   hearts     6
## 48  five   hearts     5
## 49  four   hearts     4
## 50 three   hearts     3
## 51   two   hearts     2
## 52   ace   hearts     1
# This code won't work because R will
# be in a runtime environment when it
# executes deck <- deck[-1, ]. Instead
# of overwriting the global copy of 
# deck with deck[-1, ], deal will 
# just create a slightly altered copy
# of deck in its runtime environment
# You can assign an object to a specific 
# environment with the assign function:
deal <- function(){
  card <- deck[1,]
  assign("deck",deck[-1,],envir=globalenv())
  card
}
deal()
##    face   suit value
## 2 queen spades    12
deal()
##   face   suit value
## 3 jack spades    11
#Let's turn our attention to the shuffle function:
# shuffle <- function(cards){
#   random <- sample(1:52,size = 52)
#   cards[random,]
# }
# shuffle(cards)
# head(deck)
a <- shuffle(deck)
head(deck)
##    face   suit value
## 4   ten spades    10
## 5  nine spades     9
## 6 eight spades     8
## 7 seven spades     7
## 8   six spades     6
## 9  five spades     5
head(a,3)
##     face     suit value
## 11 three   spades     3
## 4    ten   spades    10
## 34   six diamonds     6
# This behavior is now undesirable in two ways.
# First, shuffle fails to shuffle deck.
# Second, shuffle returns a copy of deck,
# which may be missing the cards that have
# been dealt away. It would be better if
# shuffle returned the dealt cards to 
# the deck and then shuffled. 
# This is what happens when you shuffle
# a deck of cards in real life.
shuffle <- function(){
  random <- sample(1:52,size=52)
  assign(deck,DECK[random,],envir = globalenv())
  
}
# Since DECK lives in the global environment, 
# shuffle's environment of origin, shuffle
# will be able to find DECK at runtime.
# R will search for DECK first in shuffle's
# runtime environment, and then in shuffle's
# origin environment-the global environment-which
# # is where DECK is stored.
# The second line of shuffle will create a 
# reordered copy of DECK and save it as deck 
# in the global environment
# This willoverwrite the previous, nonshuffled
# version of deck.
ls(globalenv())
##  [1] "a"             "add"           "deal"          "deck"         
##  [5] "DECK"          "deck_2"        "deck_3"        "deck_4"       
##  [9] "deck_5"        "deck2"         "deck3"         "dice"         
## [13] "die"           "facecard"      "foo"           "hand1"        
## [17] "hand2"         "now"           "queenOfspades" "random"       
## [21] "roll"          "roll2"         "roll3"         "roll4"        
## [25] "rolls"         "show_env"      "shuffle"       "w"            
## [29] "x"             "x3"            "y"             "z"
head(globalenv()$deck,3)
##    face   suit value
## 4   ten spades    10
## 5  nine spades     9
## 6 eight spades     8
assign("new","Hello Global",envir = globalenv())
globalenv()$new
## [1] "Hello Global"
new <- "Hello Active"
new
## [1] "Hello Active"
show_env <- function(){
  list(ran.in=environment(),
       parent=parent.env(environment()),
       objects=ls.str(environment()))
}
show_env()
## $ran.in
## <environment: 0x050777fc>
## 
## $parent
## <environment: R_GlobalEnv>
## 
## $objects
# The results reveal that R created a new environment
# named 0x03e9e8f0 to run show_env() in.
# The environment had no objects in it, 
# and its parent was the global environment.
show_env()
## $ran.in
## <environment: 0x0543a620>
## 
## $parent
## <environment: R_GlobalEnv>
## 
## $objects
# This time show_env ran in a new environment,
# 0x11476c48. R creates a new environment
# each time you run a function. The 0x11476c48
# environment looks exactly the same as 0x03e9e8f0 .
# It is empty and has the same global environment
# as its parent.
# Now let's consider which environment R will 
# use as the parent of the runtime environment.
# R will connect a function's runtime environment
# to the environment that the function was first 
# created in. This environment plays an important
# role in the function's life-because all of the
# function's runtime environments will use it 
# as a parent. Let's call this environment 
# the origin environment. You can look up a
# function's origin environment by running 
# environment on the function:
environment(show_env)
## <environment: R_GlobalEnv>
# The origin environment of show_env is the 
# global environment because we created 
# show_env at the command line, but the origin
# environment does not need to be the
# global environment. For example, the environment
# of parenvs is the pryr package:
environment(parenvs)
## <environment: namespace:pryr>
# In other words, the parent of a runtime 
# environment will not always be the global
# environment; it will be whichever environment
# the function was first created in.
# Finally, let's look at the objects contained
# in a runtime environment. At the moment,
# show_env's runtime environments do not 
# contain any objects, but that is easy to fix.
# Just have show_env create some objects
# in its body of code. R will store any 
# objects created by show_env in its runtime
# environment. Why? Because the runtime 
# environment will be the active environment
# when those objects are created:
show_env <- function(){
  a <- 1
  b <- 2
  c <- 3
  list(ran.in=environment(),
       objects=ls.str(environment()))
}
show_env()
## $ran.in
## <environment: 0x08a4be20>
## 
## $objects
## a :  num 1
## b :  num 2
## c :  num 3
# How can you use this knowledge to fix 
# the deal and shuffle functions?
deal <- function(){
  deck[1,]
}
environment(deal)
## <environment: R_GlobalEnv>
# When deal calls deck, R will need to 
# look up the deck object. R's scoping 
# rules will lead it to the version of
# deck in the global environment, 
# as in Figure 6-5. deal works as 
# expected as a result:
deal()
##   face   suit value
## 4  ten spades    10
# Now let's fix the deal function to remove 
# the cards it has dealt from deck. Recall
# that deal returns the top card of deck but 
# does not remove the card from the deck. 
# As a result, deal always returns the same card:
deal()
##   face   suit value
## 4  ten spades    10
# You know enough R syntax to remove the top card
# of deck. The following code will save a pristine
# copy of deck and then remove the top card:
DECK <- deck
deck <- deck[-1,]
head(deck,3)
##    face   suit value
## 5  nine spades     9
## 6 eight spades     8
## 7 seven spades     7
# Now let's add the code to deal. Here deal saves
# (and then returns) the top card of deck. 
# In between, it removes the card from
# deck.or does it?
deal <- function(){
  card <- deck[1,]
  deck <- deck[-1,]
  card
}
deal()
##   face   suit value
## 5 nine spades     9
deal()
##   face   suit value
## 5 nine spades     9
# This code won't work because R will be in a
# runtime environment when it executes 
# deck <- deck[-1, ]. Instead of overwriting
# the global copy of deck with deck[-1, ], deal
# will just create a slightly altered copy of 
# deck in its runtime environment,
# You can assign an object to a specific environment
# with the assign function:
deal <- function(){
  card <- deck[1,]
  assign("deck",deck[-1,],envir = globalenv())
  card
}
# Now deal will finally clean up the global
# copy of deck, and we can deal cards just 
# as we would in real life:
deal()
##   face   suit value
## 5 nine spades     9
deal()
##    face   suit value
## 6 eight spades     8
#Let's turn our attention to the shuffle function:
shuffle <- function(cards){
  random <- sample(1:52,size = 52)
  cards[random,]
}
# shuffle(deck) doesn't shuffle the deck object; 
# it returns a shuffled copy of the deck object:
a <- shuffle(deck)
head(deck,3)
##    face   suit value
## 7 seven spades     7
## 8   six spades     6
## 9  five spades     5
head(a,3)
##     face     suit value
## 45 eight   hearts     8
## 37 three diamonds     3
## 11 three   spades     3
# This behavior is now undesirable in two ways.
# First, shuffle fails to shuffle deck. 
# Second, shuffle returns a copy of deck, 
# which may be missing the cards that have
# been dealt away. It would be better if 
# shuffle returned the dealt cards to the
# deck and then shuffled. This is what 
# happens when you shuffle a deck of 
# cards in real life.
# You can update shuffle in the same way that
# you updated deck. The following version will
# do the job:
shuffle <- function(){
  random <- sample(1:52,size = 52)
  assign("deck",DECK[random,],envir = globalenv())
}
# Since DECK lives in the global environment,
# shuffle's environment of origin, shuffle
# will be able to find DECK at runtime. 
# R will search for DECK first in shuffle's 
# runtime environment, and then in shuffle's
# origin environment-the global environment-which
# is where DECK is stored.
# The second line of shuffle will create a 
# reordered copy of DECK and save it as deck
# in the global environment. This will overwrite
# the previous, nonshuffled version of deck.
# Our system finally works. For example, 
# you can shuffle the cards and then deal
# a hand of blackjack:
shuffle()
deal()
##   face   suit value
## 4  ten spades    10
deal()
##    face   suit value
## 7 seven spades     7
# Closures
# But the system requires deck and DECK to 
# exist in the global environment. Lots of 
# things happen in this environment, and 
# it is possible that deck may get modified
# or erased by accident.
# It would be better if we could store deck 
# in a safe, out-of-the-way place, like one
# of those safe, out-of-the-way environments
# that R creates to run functions in. In fact,
# storing deck in a runtime environment 
# is not such a bad idea.
# You could create a function that takes deck
# as an argument and
# saves a copy of deck as DECK. The function 
# could also save its own copies of deal and shuffle:
setup <- function(deck){
  DECK <- deck
  DEAL <- function(){
    card <- deck[-1,]
    assign("deck",deck[-1],envir = globalenv())
    card
  }
  SHUFFLE <- function(){
    random <- sample(1:52,size = 52)
    assign("deck",DECK[random,],envir = globalenv())
  }
}
# When you run setup, R will create a runtime
# environment to store these objects in. 
# The environment will look like Figure 6-7.
# Now all of these things are safely out of 
# the way in a child of the global environment.
# That makes them safe but hard to use.
# Let's ask setup to return DEAL and SHUFFLE
# so we can use them. The best way to do this
# is to return the functions as a list
setup <- function(deck){
  DECK <- deck
  DEAL <- function(){
    card <- deck[-1,]
    assign("deck",deck[-1],envir = globalenv())
    card
  }
  SHUFFLE <- function(){
    random <- sample(1:52,size = 52)
    assign("deck",DECK[random,],envir = globalenv())
  }
  list(deal=DEAL,shuffle=SHUFFLE)
}
cards <- setup(deck)
# Then you can save each of the elements of 
# the list to a dedicated object in 
# the global environment:
deal <- cards$deal
shuffle <- cards$shuffle
# Now you can run deal and shuffle just as before.
# Each object contains the same code as the 
# original deal and shuffle
deal
## function(){
##     card <- deck[-1,]
##     assign("deck",deck[-1],envir = globalenv())
##     card
##   }
## <environment: 0x083efbbc>
shuffle
## function(){
##     random <- sample(1:52,size = 52)
##     assign("deck",DECK[random,],envir = globalenv())
##   }
## <environment: 0x083efbbc>
# However, the functions now have one important
# difference. Their origin environment is no
# longer the global environment (although deal 
# and shuffle are currently saved there). 
# Their origin environment is the runtime 
# environment that R made when you ran setup. 
# That's where R created DEAL and SHUFFLE, 
# the functions copied into the new deal
# and shuffle, as shown in:
environment(deal)
## <environment: 0x083efbbc>
environment(shuffle)
## <environment: 0x083efbbc>
# Why does this matter? Because now when you run
# deal or shuffle, R will evaluate the functions
# in a runtime environment that uses 0x7ff7169c3390 
# as its parent. DECK and deck will be in this
# parent environment, which means that deal and
# shuffle will be able to find them at runtime.
# DECK and deck will be in the functions' search
# path but still out of the way in every other
# respect
# This arrangement is called a closure. 
# setup's runtime environment "encloses"
# the deal and shuffle functions. Both deal
# and shuffle can work closely with the
# objects contained
# in the enclosing environment, but almost
# nothing else can. The enclosing environment
# is not on the search path for any other
# R function or environment.
# You may have noticed that deal and shuffle
# still update the deck object in the global
# environment. Don't worry, we're about to change that.
# We want deal and shuffle to work exclusively
# with the objects in the parent (enclosing)
# environment of their runtime environments.
# Instead of having each function reference 
# the global environment to update deck, 
# you can have them reference their parent
# environment at runtime,
setup <- function(deck){
  DECK <- deck
  DEAL <- function(){
    card <- deck[1,]
    assign("deck",deck[-1,],envir = parent.env(environment()))
    card
  }
  SHUFFLE <- function(){
    random <- sample(1:52,size = 52)
    assign("deck",DECK[random,1],envir = parent.env(environment()))
  }
  list(deal=DEAL,shuffle=SHUFFLE)
}
cards <- setup(deck)
deal <- cards$deal
deck <- cards$shuffle
# We finally have a self-contained card game. 
# You can delete (or modify) the global copy 
# of deck as much as you want and still play
# cards. deal and shuffle will use the pristine,
# protected copy deck
rm(deck)
shuffle()
deal()
##    face   suit value
## 6 eight spades     8
deal()
##    face suit value
## NA <NA> <NA>    NA
# Summary
# R saves its objects in an environment system
# that resembles your computer's file system.
# If you understand this system, you can predict
# how R will look up objects. If you call an
# object at the command line, R will look for 
# the object in the global environment and then
# the parents of the global environment, working
# its way up the environment tree one 
# environment at a time.
# R will use a slightly different search 
# path when you call an 
# object from inside of a function. When you
# run a function, R creates a new environment
# to execute commands in. This environment will
# be a child of the environment where the
# function was originally defined. This may
# be the global environment, but it also may
# not be. You can use this behavior 
# to create closures, which are functions
# linked to objects in protected environments.
# As you become familiar with R's environment 
# system, you can use it to produce elegant 
# results, like we did here. However,
# the real value of understanding the
# environment system comes from knowing 
# how R functions do their job. You can
# use this knowledge to figure out what is
# going wrong when a function does not
# perform as expected.