I want to figure out how many cards in the deck are either of the suit spades OR have an even value but I can't understand out why I get different answers depending on how I write the last sections of code. The answer I'm looking to get is 31.
Suits <- c("Diamonds", "Clubs", "Hearts", "Spades")
Value <- 1:13
Deck <- expand.grid(Value = Value, Suits = Suits)
Deck$Cards <- paste(Deck$Suits, Deck$Value)
Hearts <- subset(Deck, Suits == "Hearts", "Cards")
Nines <- subset(Deck, Value == 9, "Cards")
Spades <- subset(Deck, Suits == "Spades", "Cards")
Even_Value <- subset(Deck, Value %% 2 == 0, "Cards")
length(union(Spades, Even_Value))
Spades <- Deck[Deck$Suits == "Spades", "Cards"]
Even_Value <- Deck[Deck$Value %% 2 == 0, "Cards"]
length(union(Spades, Even_Value))
CodePudding user response:
The subset
function returns a data frame with a single column, whereas the expression Deck[Deck$Suits == "Spades", "Cards"]
returns a vector. These are not the same thing. In particular, when you try to do a union
of two data frames, you will not get a single vector, but a list with one entry for each column in each data frame.
Spades <- subset(Deck, Suits == "Spades", "Cards")
Even_Value <- subset(Deck, Value %% 2 == 0, "Cards")
union(Spades, Even_Value)
#> [[1]]
#> [1] "Spades 1" "Spades 2" "Spades 3" "Spades 4" "Spades 5" "Spades 6" "Spades 7"
#> [8] "Spades 8" "Spades 9" "Spades 10" "Spades 11" "Spades 12" "Spades 13"
#>
#> [[2]]
#> [1] "Diamonds 2" "Diamonds 4" "Diamonds 6" "Diamonds 8" "Diamonds 10" "Diamonds 12"
#> [7] "Clubs 2" "Clubs 4" "Clubs 6" "Clubs 8" "Clubs 10" "Clubs 12"
#> [13] "Hearts 2" "Hearts 4" "Hearts 6" "Hearts 8" "Hearts 10" "Hearts 12"
#> [19] "Spades 2" "Spades 4" "Spades 6" "Spades 8" "Spades 10" "Spades 12"
Since you passed two data frames each with one column, there are 2 * 1 = 2 vectors in the resulting list, so it is a list of length 2.
Similarly if you did a union
of the built-in data sets iris
and mtcars
, you would get a list of 16 vectors (all 5 columns from iris
and all 11 columns from mtcars
):
ncol(mtcars)
#> [1] 11
ncol(iris)
#> [1] 5
length(union(mtcars, iris))
#> [1] 16
However, the second version performs the union of two vectors rather than two dataframes, and the union
of these two vectors will be correct:
Spades <- Deck[Deck$Suits == "Spades", "Cards"]
Even_Value <- Deck[Deck$Value %% 2 == 0, "Cards"]
union(Spades, Even_Value)
#> [1] "Spades 1" "Spades 2" "Spades 3" "Spades 4" "Spades 5" "Spades 6"
#> [7] "Spades 7" "Spades 8" "Spades 9" "Spades 10" "Spades 11" "Spades 12"
#> [13] "Spades 13" "Diamonds 2" "Diamonds 4" "Diamonds 6" "Diamonds 8" "Diamonds 10"
#> [19] "Diamonds 12" "Clubs 2" "Clubs 4" "Clubs 6" "Clubs 8" "Clubs 10"
#> [25] "Clubs 12" "Hearts 2" "Hearts 4" "Hearts 6" "Hearts 8" "Hearts 10"
#> [31] "Hearts 12"
To make the first version work, you must select the column of the data frame from which you wish to make the union (in each case, it is the only column - Cards
, but this still needs to be selected to obtain the vector in the data frame rather than the data frame itself)
Spades <- subset(Deck, Suits == "Spades", "Cards")
Even_Value <- subset(Deck, Value %% 2 == 0, "Cards")
length(union(Spades$Cards, Even_Value$Cards))
#> [1] 31