【问题标题】:Filter one column by matching to another column通过匹配另一列来过滤一列
【发布时间】:2019-05-28 15:07:09
【问题描述】:

我有一个数据框,其中包含一个变量,如果它们与另一个变量中的元素匹配,则要删除的元素 - 请参见下面的小示例:

df <- data.frame(pair = c(1, 1, 2, 2, 3, 3),
                 animal = rep(c("dog", "cat"), 3), 
                 value = seq(1, 12, 2), 
                 drop = c("no", "no", "dog", "dog", "cat", "cat"))

  pair animal value drop
1    1    dog     1   no
2    1    cat     3   no
3    2    dog     5  dog
4    2    cat     7  dog
5    3    dog     9  cat
6    3    cat    11  cat

我试图根据animal 的值是否与drop 的值匹配来过滤数据框。我想要filter(df, animal != drop) 之类的东西来删除只有animal 的值与drop 的值匹配的行:

  pair animal value drop
1    1    dog     1   no
2    1    cat     3   no
4    2    cat     7  dog
5    3    dog     9  cat

我还尝试编写一个简单的循环来测试动物匹配是否为每一行删除,如果为真则删除该行,但我无法让它工作。 (我对循环不是很有信心,如果可能的话,我宁愿不使用循环,因为我的数据框非常大,但我越来越绝望了!)

for(i in nrow(df)){
  if(df$animal[i] == df$drop[i]){
    df <- df[-i,]
    return(df)
  }
}

有没有办法使用 dplyr 做到这一点?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    filter(df, animal != drop) 的使用是正确的。但是,由于您没有在data.frame() 调用中指定stringsAsFactors = F,因此所有字符串都转换为因子,从而提高了不同级别集的错误。因此添加stringsAsFactors = F,应该可以解决这个问题

    df <- data.frame(pair = c(1, 1, 2, 2, 3, 3),
                     animal = rep(c("dog", "cat"), 3), 
                     value = seq(1, 12, 2), 
                     drop = c("no", "no", "dog", "dog", "cat", "cat"),
                     stringsAsFactors = F) 
    
    df %>%
      filter(animal != drop)
    
      pair animal value drop
    1    1    dog     1   no
    2    1    cat     3   no
    3    2    cat     7  dog
    4    3    dog     9  cat
    

    为了避免这种不受欢迎的字符串因素行为出现问题,我强烈建议使用tibble

    如果没有机会更改数据的创建方式,我在这里提供@akrun 的解决方案:

    library(dplyr)
    
    df %>% 
      mutate_at(vars(animal, drop), as.character) %>%       
      filter(animal != drop)
    #  pair animal value drop
    #1    1    dog     1   no
    #2    1    cat     3   no
    #3    2    cat     7  dog
    #4    3    dog     9  cat
    

    【讨论】:

    • 在本例中这是一个很好的解决方案,但请考虑您无法控制如何创建数据框的情况。在我的日常工作中,我很少创建这样的数据框——如果我这样做了,我的工作会更容易!也许您可以添加您将如何处理目前这是一个因素这一事实
    • 这是我的问题,谢谢 - 我的原始数据框是一个 tibble,但我没有考虑到我的变量之一是因子类。 filter(animal != as.character(drop) 工作完美,无需删除这些因素。
    • 添加了@akrun的解决方案
    【解决方案2】:

    一种选择是使用mutate_at 转换为character 类,然后在不匹配的元素上使用filter

    library(dplyr)
    df %>% 
      mutate_at(vars(animal, drop), as.character) %>%       
      filter(animal != drop)
    #  pair animal value drop
    #1    1    dog     1   no
    #2    1    cat     3   no
    #3    2    cat     7  dog
    #4    3    dog     9  cat
    

    【讨论】:

      猜你喜欢
      • 2021-12-12
      • 1970-01-01
      • 2020-05-28
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 2021-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多