Delete entries with only one observation in a group

With your sample data

DG <- read.csv(text="day,City,age
4-10,Miami,30
4-10,Miami,23
4-11,New York,24
4-12,San Francisco,30")

you could use dplyr

library(dplyr)
DG %>% group_by(day,City) %>% filter(n()>1)

or base R

DG[ave(rep(1, nrow(DG)), DG$day, DG$City, FUN=length)>1,]

both return

   day  City age
1 4-10 Miami  30
2 4-10 Miami  23

Or you could use data.table (as suggested by @Frank)

library(data.table)
setDT(DG)[,if (.N>1) .SD, by=.(City,day)]

MrFlick's answer is (as usual) hard to top, but here's my longer version, which instead serves as a great way to get in some practice with dplyr.

Here's the dataframe:

DG <- data.frame(day=c('4-10', 4-10', '4-11', '4-12'), City=c('Miami', 'Miami', 'New York', 'San Francisco'), age=c(30, 23, 23, 30))

Using group_by, we group the cities together, then pipe the groupings into summarize using n(), which is a handy dplyr function.

DG1 <- DG %>%
  group_by(City, day) %>%
  summarize(n=n())
#          City  day n
#         Miami 4-10 2
#      New York 4-11 1
# San Francisco 4-12 1

Turn DG1 into a regular dataframe, just to be on the safe side:

DG2 <- data.frame(DG1)

...and then we get rid of unwanted rows via filter, based on what appeared more than once.

DG3 <- filter(DG2, n>1)
#City  day  n
#Miami 4-10 2

Next, use select to get columns (whereas we just used filter to get rows). This just gets rid of the column n.

DG4 <- select(DG3, City, day)
#City  day
#Miami 4-10

Finally, we use filter on the original dataframe to get all the cities that have multiple occurances. These cities with multiple occurances now live in DG4 (hence City==DG4$City):

DG5 <- filter(DG, City==DG4$City)
#day  City   age
#4-10 Miami  30
#4-10 Miami  23

Again, I'd go with MrFlick's answer, but if you feel like a more circuitous route with a few more dplyr functions, you might want to give this a quick look.

Tags:

R