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.
On 03/01/2019 12:39 p.m., Benoit Galarneau wrote:> 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?I think the answer to "recommended or good practice" depends on your priorities. If I was running a big simulation where speed really matters, I wouldn't do it that way: dataframes are slow and looking for a name in a vector of names can be slow. You'd get faster results using matrices and row indices (which can be negated to remove items, as you know.) But then you have to deal with the issue that matrices can't mix types as your dataframe does, so your code is likely to be less clear. If speed isn't so much of an issue but clarity is, then you really want to write your own small functions to do the removal, e.g. whichCard <- function(deck, card) { which(deck$face == card$face & deck$suit == card$suit & deck$value = card$value) } removeCard <- function(deck, card) { deck[-whichCard(deck, card), ] } deck <- removeCard(deck, topCard) Duncan Murdoch> 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. > > ______________________________________________ > 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. >
On 03/01/2019 12:39 p.m., Benoit Galarneau wrote:> 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?I forgot to address "safety". Your code above will only be safe if you can guarantee that topCard is always produced by subsetting the deck. If a user does something like topCard <- data.frame(face = "queen", suit = "spades", value = 12) then the rownames won't match, and removing topCard will remove the wrong one. Duncan Murdoch> > 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. > > ______________________________________________ > 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. >
Many thanks everyone for the rich feedback. Very impressive. I will digest all the information received and continue on my learning around R. Benoit Duncan Murdoch <murdoch.duncan at gmail.com> a ?crit?:> On 03/01/2019 12:39 p.m., Benoit Galarneau wrote: >> 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? > > I forgot to address "safety". Your code above will only be safe if > you can guarantee that topCard is always produced by subsetting the > deck. If a user does something like > > topCard <- data.frame(face = "queen", suit = "spades", value = 12) > > then the rownames won't match, and removing topCard will remove the > wrong one. > > Duncan Murdoch > >> >> 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. >> >> ______________________________________________ >> 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. >>
AFAIK the intent of the designers of the data frame class was that rownames be unique and be useful for tracking the origins of records in data subsets. However, after a few merging operations the traceability becomes murky anyway and relational set theory avoids them. Neither data.table nor dplyr packages support them. In short, base R data import functions will create rownames on data frames so you should be able to depend on it as long as you stick with base R. On January 3, 2019 9:39:44 AM PST, Benoit Galarneau <benoit.galarneau at polymtl.ca> wrote:>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.-- Sent from my phone. Please excuse my brevity.
Here is another approach that uses only the default packages:> onecar <- mtcars[10,] > w <- which(duplicated(rbind(mtcars,onecar), fromLast = TRUE)) > w[1] 10> mtcars.subset <- mtcars[-w,] > > > threecars <- mtcars[c(1,10,15),] > w <- which(duplicated(rbind(mtcars,threecars), fromLast=TRUE)) > w[1] 1 10 15> mtcars.subset <- mtcars[-w, ]This works with a subset of 1, or more than 1, but could cause problems if you have duplicate rows in your original data frame. If you are willing to use a non-default package then there are many possibilities. The anti_join function from the dplyr package has already been mentioned, but the setdiff function from dplyr would also work here and would be a little simpler for your example:> library(dplyr) > mtcars.subset2 <- setdiff(mtcars,threecars) > identical(as.list(mtcars.subset), as.list(mtcars.subset2))[1] TRUE The as.list function above was to remove some attributes that were different between the outputs. On Thu, Jan 3, 2019 at 10:59 AM Benoit Galarneau <benoit.galarneau at polymtl.ca> wrote:> > 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. > > ______________________________________________ > 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.-- Gregory (Greg) L. Snow Ph.D. 538280 at gmail.com