根据两个单独的匹配要求删除一行

时间:2018-10-02 03:46:51

标签: r

如果有关于此的帖子,我表示歉意-我搜索了很多次答案,却找不到任何有效的方法。

我需要做的是,仅在存在重复的动物类型而不是66的情况下,删除下面示例中等于66的所有行。

animals <- c("dog", "dog", "dog", "cat", "cat", "cat", "mouse", "mouse", "rat", "rat")
number <- c(1,2,66,2,66,66,66,66,2,1)

df <- data.frame(animals,number)

使用df我想删除第3行,因为dog的其他值分别为1和2,我想删除cat的66都因为存在cat的其他值2,但是我不想删除要么是鼠标输入,因为它们都是66,我不想用rat删除任何东西,因为没有66值。

我最终会得到类似的结果:

animals <- c("dog", "dog", "cat", "mouse", "mouse", "rat", "rat")
number <- c(1,2,2,66,66,2,1) 

在实际数据集中,有太多条目,您根本无法使用计数并删除总计少于66的所有内容(这是我的本能)

这是我的第二次尝试,但由于某些原因无法思考。

df(!number == 66 | if(unique(animals) ==

也许涉及哪个陈述?任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:5)

使用基数R ave的一种方法,在该方法中,我们检查是否有动物的数字不是66,如果有,则返回忽略66的数字,否则返回所有行。

df[with(df, ave(number != 66, animals, FUN = function(x) if (any(x)) x else !x)), ]


#  animals number
#1     dog      1
#2     dog      2
#3     cat      2
#4   mouse     66
#5   mouse     66
#6     rat      2
#7     rat      1

dplyr版本将filter包含全部66个的组,否则将忽略包含66个的行。

library(dplyr)

df %>%
   group_by(animals) %>%
   filter(all(number == 66) | number != 66)

# animals number
#  <fct>    <dbl>
#1 dog          1
#2 dog          2
#3 cat          2
#4 mouse       66
#5 mouse       66
#6 rat          2
#7 rat          1

答案 1 :(得分:1)

使用dplyr

library(dplyr)
df %>% group_by(animals) %>%
  mutate(Flag= case_when( number %in% c(1,2) ~ 1,
                          all(number == 66) ~ 1,
                          number == 66 ~ 0)) %>% 
  filter(Flag==1) %>% select(-Flag) %>% ungroup()


# A tibble: 7 x 2
animals number
<chr>    <dbl>
1 dog         1.
2 dog         2.
3 cat         2.
4 mouse      66.
5 mouse      66.
6 rat         2.
7 rat         1.