Hi everyone, I'm new to the R world. Probably a newbie question but I am stuck with some concept with data frame. I am following some examples in the "Hands-On Programming with R". In short, how can I access/filter items in a data frame using a variable. One example consists of manipulating elements from a deck of card:> deckface suit value 1 king spades 13 2 queen spades 12 3 jack spades 11 4 ten spades 10 etc. Let's say I want to remove or filter out the first card. I know I could do deck[-1]. But let's say I have: topCard <- deck[1,] topCard is then a list of 3 elements> topCardface suit value 1 king spades 13 My question is the following, how can I remove or filter out the deck using the topCard variable. In my programmer's head, something similar to this should "work":> deck[10,]face suit value 10 four spades 4> aCard <- deck[10,] > aCardface suit value 10 four spades 4> deck[aCard]Error in `[.default`(deck, aCard) : invalid subscript type 'list' Wihout having to specify all elements in the logical tests. deck[deck$face == aCard$face & deck$suit == aCard$suit & deck$value == aCard$value,] face suit value 10 four spades 4
Hello, Inline. ?s 14:50 de 03/01/2019, Benoit Galarneau escreveu:> Hi everyone, > I'm new to the R world. > Probably a newbie question but I am stuck with some concept with data > frame. > I am following some examples in the "Hands-On Programming with R". > > In short, how can I access/filter items in a data frame using a variable. > > One example consists of manipulating elements from a deck of card: > >> deck > ??? face???? suit value > 1?? king?? spades??? 13 > 2? queen?? spades??? 12 > 3?? jack?? spades??? 11 > 4??? ten?? spades??? 10 > etc. > > Let's say I want to remove or filter out the first card. I know I could > do deck[-1].No, to filter out the first card you need a comma after the -1. deck[-1, ] # filter the first row out deck[-1] # filter the first column out> > But let's say I have: topCard <- deck[1,] > > topCard is then a list of 3 elements >> topCard > ? face?? suit value > 1 king spades??? 13 > > My question is the following, how can I remove or filter out the deck > using the topCard variable.merge(topCard, deck, all.x = TRUE, all.y = FALSE) Hope this helps, Rui Barradas> > In my programmer's head, something similar to this should "work": >> deck[10,] > ?? face?? suit value > 10 four spades???? 4 >> aCard <- deck[10,] >> aCard > ?? face?? suit value > 10 four spades???? 4 >> deck[aCard] > Error in `[.default`(deck, aCard) : invalid subscript type 'list' > > Wihout having to specify all elements in the logical tests. > > deck[deck$face == aCard$face & deck$suit == aCard$suit & deck$value == > aCard$value,] > ?? face?? suit value > 10 four spades???? 4 > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
Hi Benoit, You can select rows from deck matched in aCard using merge(deck, aCard) Selecting rows that don't match is bit more difficult. You could do something like isin <- apply(mapply(function(x, y) x %in% y, deck, topCard), 1, all) deck[!isin, ] perhaps. Alternatively, you can use anti_join from the dplyr package: library(dplyr) anti_join(deck, topCard) Best, Ista On Thu, Jan 3, 2019 at 10:38 AM Benoit Galarneau <benoit.galarneau at polymtl.ca> wrote:> > Hi everyone, > I'm new to the R world. > Probably a newbie question but I am stuck with some concept with data frame. > I am following some examples in the "Hands-On Programming with R". > > In short, how can I access/filter items in a data frame using a variable. > > One example consists of manipulating elements from a deck of card: > > > deck > face suit value > 1 king spades 13 > 2 queen spades 12 > 3 jack spades 11 > 4 ten spades 10 > etc. > > Let's say I want to remove or filter out the first card. I know I > could do deck[-1]. > > But let's say I have: topCard <- deck[1,] > > topCard is then a list of 3 elements > > topCard > face suit value > 1 king spades 13 > > My question is the following, how can I remove or filter out the deck > using the topCard variable. > > In my programmer's head, something similar to this should "work": > > deck[10,] > face suit value > 10 four spades 4 > > aCard <- deck[10,] > > aCard > face suit value > 10 four spades 4 > > deck[aCard] > Error in `[.default`(deck, aCard) : invalid subscript type 'list' > > Wihout having to specify all elements in the logical tests. > > deck[deck$face == aCard$face & deck$suit == aCard$suit & deck$value => aCard$value,] > face suit value > 10 four spades 4 > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
You are correct, the anti_join is working fine. However, I still find it strange there is no "quick" way to find the index of an item extracted from the data frame. This works as it returns the deck without the card no 10. aCard = deck[10,] cardNo = which(deck$value == aCard$value & deck$suit == aCard$suit) deck[-cardNo,] But I'm still puzzled by the complexity of finding back the index of the card with the long statement. Another approach that "works" is the following, but I still find it strange to depend on data frame row names to find the index: cardNo <- as.numeric(row.names(aCard)) Apologies if the above question are strange. I'm coming C++ world with some bias with objects. Again, since "aCard" is extracted from the data frame, I assume (bias?) there would be a simple way to find back the item in the data frame it came frame. Some kind of indexOf() or similar on the container and item. Benoit Ista Zahn <istazahn at gmail.com> a ?crit?:> Hi Benoit, > > You can select rows from deck matched in aCard using > > merge(deck, aCard) > > Selecting rows that don't match is bit more difficult. You could do > something like > > isin <- apply(mapply(function(x, y) x %in% y, deck, topCard), > 1, > all) > deck[!isin, ] > > perhaps. > > Alternatively, you can use anti_join from the dplyr package: > > library(dplyr) > anti_join(deck, topCard) > > Best, > Ista > > On Thu, Jan 3, 2019 at 10:38 AM Benoit Galarneau > <benoit.galarneau at polymtl.ca> wrote: >> >> Hi everyone, >> I'm new to the R world. >> Probably a newbie question but I am stuck with some concept with data frame. >> I am following some examples in the "Hands-On Programming with R". >> >> In short, how can I access/filter items in a data frame using a variable. >> >> One example consists of manipulating elements from a deck of card: >> >> > deck >> face suit value >> 1 king spades 13 >> 2 queen spades 12 >> 3 jack spades 11 >> 4 ten spades 10 >> etc. >> >> Let's say I want to remove or filter out the first card. I know I >> could do deck[-1]. >> >> But let's say I have: topCard <- deck[1,] >> >> topCard is then a list of 3 elements >> > topCard >> face suit value >> 1 king spades 13 >> >> My question is the following, how can I remove or filter out the deck >> using the topCard variable. >> >> In my programmer's head, something similar to this should "work": >> > deck[10,] >> face suit value >> 10 four spades 4 >> > aCard <- deck[10,] >> > aCard >> face suit value >> 10 four spades 4 >> > deck[aCard] >> Error in `[.default`(deck, aCard) : invalid subscript type 'list' >> >> Wihout having to specify all elements in the logical tests. >> >> deck[deck$face == aCard$face & deck$suit == aCard$suit & deck$value =>> aCard$value,] >> face suit value >> 10 four spades 4 >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code.
>In my programmer's head, something similar to this should "work": ... > deck[aCard]There are some people who agree with you... see the data.table package, which can be made to behave like this. Keep in mind that the aCard data frame in general may have a different set of column names or more than one row. (I would be concerned that the logic of your application was inefficiently designed if `deck` actually has the same columns as `aCard` as in your example.) Others have pointed out that data frames are typically combined using the merge function, which allows matching columns to be specified very flexibly. On January 3, 2019 6:50:22 AM PST, Benoit Galarneau <benoit.galarneau at polymtl.ca> wrote:>Hi everyone, >I'm new to the R world. >Probably a newbie question but I am stuck with some concept with data >frame. >I am following some examples in the "Hands-On Programming with R". > >In short, how can I access/filter items in a data frame using a >variable. > >One example consists of manipulating elements from a deck of card: > >> deck > face suit value >1 king spades 13 >2 queen spades 12 >3 jack spades 11 >4 ten spades 10 >etc. > >Let's say I want to remove or filter out the first card. I know I >could do deck[-1]. > >But let's say I have: topCard <- deck[1,] > >topCard is then a list of 3 elements >> topCard > face suit value >1 king spades 13 > >My question is the following, how can I remove or filter out the deck >using the topCard variable. > >In my programmer's head, something similar to this should "work": >> deck[10,] > face suit value >10 four spades 4 >> aCard <- deck[10,] >> aCard > face suit value >10 four spades 4 >> deck[aCard] >Error in `[.default`(deck, aCard) : invalid subscript type 'list' > >Wihout having to specify all elements in the logical tests. > >deck[deck$face == aCard$face & deck$suit == aCard$suit & deck$value == > >aCard$value,] > face suit value >10 four spades 4 > >______________________________________________ >R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >https://stat.ethz.ch/mailman/listinfo/r-help >PLEASE do read the posting guide >http://www.R-project.org/posting-guide.html >and provide commented, minimal, self-contained, reproducible code.-- Sent from my phone. Please excuse my brevity.
Thanks for the feedback. Point taken about the data.table package, I will take a look for sure. As I am new to the R programming, I'm exploring with the default libraries as a start. I have various options that works like this one: topCard <- deck[1,] #Remove card from deck using row name deck <- deck[!rownames(deck) %in% row.names(topCard),] Is it recommended/safe/good practice to work on items using the item names? Benoit Jeff Newmiller <jdnewmil at dcn.davis.ca.us> a ?crit?:>> In my programmer's head, something similar to this should "work": ... >> deck[aCard] > > There are some people who agree with you... see the data.table > package, which can be made to behave like this. > > Keep in mind that the aCard data frame in general may have a > different set of column names or more than one row. (I would be > concerned that the logic of your application was inefficiently > designed if `deck` actually has the same columns as `aCard` as in > your example.) Others have pointed out that data frames are > typically combined using the merge function, which allows matching > columns to be specified very flexibly. > > > On January 3, 2019 6:50:22 AM PST, Benoit Galarneau > <benoit.galarneau at polymtl.ca> wrote: >> Hi everyone, >> I'm new to the R world. >> Probably a newbie question but I am stuck with some concept with data >> frame. >> I am following some examples in the "Hands-On Programming with R". >> >> In short, how can I access/filter items in a data frame using a >> variable. >> >> One example consists of manipulating elements from a deck of card: >> >>> deck >> face suit value >> 1 king spades 13 >> 2 queen spades 12 >> 3 jack spades 11 >> 4 ten spades 10 >> etc. >> >> Let's say I want to remove or filter out the first card. I know I >> could do deck[-1]. >> >> But let's say I have: topCard <- deck[1,] >> >> topCard is then a list of 3 elements >>> topCard >> face suit value >> 1 king spades 13 >> >> My question is the following, how can I remove or filter out the deck >> using the topCard variable. >> >> In my programmer's head, something similar to this should "work": >>> deck[10,] >> face suit value >> 10 four spades 4 >>> aCard <- deck[10,] >>> aCard >> face suit value >> 10 four spades 4 >>> deck[aCard] >> Error in `[.default`(deck, aCard) : invalid subscript type 'list' >> >> Wihout having to specify all elements in the logical tests. >> >> deck[deck$face == aCard$face & deck$suit == aCard$suit & deck$value =>> >> aCard$value,] >> face suit value >> 10 four spades 4 >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide >> http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. > > -- > Sent from my phone. Please excuse my brevity.
See below.> On Jan 3, 2019, at 6:50 AM, Benoit Galarneau <benoit.galarneau at polymtl.ca> wrote: > > Hi everyone, > I'm new to the R world. > Probably a newbie question but I am stuck with some concept with data frame. > I am following some examples in the "Hands-On Programming with R". > > In short, how can I access/filter items in a data frame using a variable. > > One example consists of manipulating elements from a deck of card: > >> deck > face suit value > 1 king spades 13 > 2 queen spades 12 > 3 jack spades 11 > 4 ten spades 10 > etc. > > Let's say I want to remove or filter out the first card. I know I could do deck[-1]. > > But let's say I have: topCard <- deck[1,] > > topCard is then a list of 3 elements >> topCard > face suit value > 1 king spades 13 > > My question is the following, how can I remove or filter out the deck using the topCard variable. > > In my programmer's head, something similar to this should "work": >> deck[10,] > face suit value > 10 four spades 4 >> aCard <- deck[10,] >> aCard > face suit value > 10 four spades 4 >> deck[aCard] > Error in `[.default`(deck, aCard) : invalid subscript type 'list' > > Wihout having to specify all elements in the logical tests. > > deck[deck$face == aCard$face & deck$suit == aCard$suit & deck$value == aCard$value,] > face suit value > 10 four spades 4matchRow <- Reduce( "&", mapply("==", deck, aCard, SIMPLIFY=FALSE)) deck[ !matchRow, ] There is a little `trick' here. A "data.frame" object is a "list" object and both `deck` and `aCard` are "data.frame" objects. So using `mapply` as above operates on the successive columns of each. You will find many useful idioms using the *apply functions. As you are new to R, I recommend running the example() for each of them as well as browsing the help page. HTH, Chuck