1

I have a data frame that contains sample plot information, some of these sample plots have been subdivided by different conditions. My question is how do I remove some of the subdivided rows based on a list of the plots and conditions that need to be removed?

I've tried using this df3 <- df[!(df$PLOT %in% df2$PLOT & df$CONDID %in% df2$CONDID),] as well as similer variations with the filter() function from the dplyr package. However this just removes all plots/conditions listed in df2.

Here is a simplified version of my data:

df <- data.frame(PLOT = c(82708, 88503, 88503, 88503, 86560, 89773, 82199, 82199, 84113), 
             CONDID = c(1, 1, 2, 3, 1, 1, 1, 2, 1))
df

And the list I'm trying to use to remove certain plot/conditions looks like this:

df2 <- data.frame(PLOT = c(88503, 88503, 82199), CONDID = c(1, 3, 2))
df2

I want my output data frame to look like this:

df3 <- data.frame(PLOT = c(82708, 88503, 86560, 89773, 82199, 84113), CONDID = c(1, 2, 1, 1, 1, 1))
df3
  • 1
    Shouldn't the value for "PLOT" 88503 in df3 be 1? – tmfmnk Jan 30 '19 at 18:55
  • If the answer to the @tmfmnk's question above is "yes", the code you show and say you tried works. It may look like the result has 9 rows, but that's just because the rownames are preserved. – IceCreamToucan Jan 30 '19 at 18:59

2 Answers2

1

You can solve this issue using joins:

library(dplyr)
df3<- anti_join(df,df2, by=c("PLOT","CONDID"))
NelsonGon
  • 13,015
  • 7
  • 27
  • 57
0

The code you proposed seems to work with filter().

df %>% 
  filter(!(PLOT %in% df2$PLOT & CONDID %in% df2$CONDID))

#    PLOT CONDID
# 1 82708      1
# 2 88503      1
# 3 86560      1
# 4 89773      1
# 5 82199      1
# 6 84113      1

If you're not sure, you can break the process step by step:

df %>% 
  mutate(
    condition1 = PLOT %in% df2$PLOT,
    condition2 = CONDID %in% df2$CONDID,
    cond_1_2   = condition1 * condition2
  ) %>% 
  filter(
    cond_1_2 != 1
  ) 

#    PLOT CONDID condition1 condition2 cond_1_2
# 1 82708      1      FALSE      FALSE        0
# 2 88503      1       TRUE      FALSE        0
# 3 86560      1      FALSE      FALSE        0
# 4 89773      1      FALSE      FALSE        0
# 5 82199      1       TRUE      FALSE        0
# 6 84113      1      FALSE      FALSE        0
demarsylvain
  • 2,103
  • 2
  • 14
  • 33