Dplyr - 过滤任何变量是否等于某个值

时间:2016-05-21 13:29:20

标签: r dplyr

我有一个包含5个变量的数据集a,并希望像这样过滤它:

a1 <- a %>% filter(var_1 != 1 , var_2 != 1 , var_3 != 1 , var_4 != 1 , variable_5 != 1)

我想知道是否存在这样的(伪代码):

a1 <- a %>% filter(anyvariable != 1)

换句话说,我想摆脱价值为1的所有行,无论它出现在何处。 1只是一个随机数。它可能是9,99,或其他任何东西! 谢谢!

6 个答案:

答案 0 :(得分:5)

我们或许可以使用rowSums

a %>% 
  filter(rowSums(. !=0) >0)
#    Col1 Col2
#1    1    1
#2    0   24
#3    9    1

如果我将其更改为!=1

a %>% 
   filter(rowSums(. != 1) > 0)
#   Col1 Col2
#1    0   24
#2    9    1
#3    0    0

请注意,这将删除所有1的行。在前一种情况下,它会删除所有0的行,这与OP中提到的OP一致。

更新

如果OP想删除任何1的行(只是一个数字,他可以使用9,或99或999)

a %>% 
   filter(!rowSums(.==1))
#    Col1 Col2
#1    0   24
#2    0    0

数据

a <- data.frame(Col1 = c(1, 0, 9, 0), Col2 = c(1, 24, 1, 0))

答案 1 :(得分:3)

您可以将filter_allall_vars中的dplyr结合使用,如下所示:

some_data <- tibble(var1 = c("a", "b", "c"),
                    var2 = c(2, 4, 1),
                    var3 = c(1, 6, 5))

# # A tibble: 3 x 3
#   var1   var2  var3
#   <chr> <dbl> <dbl>
# 1 a      2.00  1.00
# 2 b      4.00  6.00
# 3 c      1.00  5.00

some_data %>% filter_all(all_vars(. != 1))

# # A tibble: 1 x 3
#   var1   var2  var3
#   <chr> <dbl> <dbl>
# 1 b      4.00  6.00

这将删除变量包含的行1.在上面的示例中,这将删除第一行和第三行。但是,要对NA值保持谨慎:

some_data <- tibble(var1 = c("a", "b", "c"),
                    var2 = c(2, NA, 1),
                    var3 = c(1, 6, 5))
# # A tibble: 3 x 3
#   var1   var2  var3
#   <chr> <dbl> <dbl>
# 1 a      2.00  1.00
# 2 b     NA     6.00
# 3 c      1.00  5.00

some_data %>% filter_all(all_vars(. != 1))  

# # A tibble: 0 x 3
# # ... with 3 variables: var1 <chr>, var2 <dbl>, var3 <dbl>

请注意,第二行不包含1,但仍会进行过滤。在此特定示例中,您可以通过以下方式避免此类行为:

some_data %>% filter_all(all_vars(. != 1 | is.na(.)))

然而,这可能不会很好地概括。

答案 2 :(得分:2)

以下是OP请求形式的一些方便功能:

> a
  Col1 Col2
1    1    1
2    0   24
3    9    1
4    0    0
> a %>% filter_exclude(test_val=1)
  Col1 Col2
1    0   24
2    0    0
> a %>% filter_any(test_val=1)
  Col1 Col2
1    1    1
2    9    1
>

以下是OP测试变量的结果:

> filter_exclude(a,test_val=1)
  Col1 Col2
1    0   24
2    0    0
> filter_any(a,test_val=1)
  Col1 Col2
1    1    1
2    9    1
>

这些功能的优点是无需使用管道符号:

class MyCrawler extends PHPCrawler  
{ 
  function handleDocumentInfo($DocInfo)  
  { 
    if (PHP_SAPI == "cli"){
      $lb = "\n"; 
    } else {
      $lb = "<br />"; 
    }
    echo "Page requested: ".$DocInfo->url." (".$DocInfo->http_status_code.")".$lb; 
    echo "Referer-page: ".$DocInfo->referer_url.$lb; 

    if ($DocInfo->received == true) {
      echo "Content received: ".$DocInfo->bytes_received." bytes".$lb; 
    }
    else {
      echo "Content not received".$lb;  
    }

    echo $lb; 
    flush(); 
  }  
} 

$crawler = new MyCrawler(); 
$crawler->setURL("www.php.net"); 
$crawler->addContentTypeReceiveRule("#text/html#"); 
$crawler->addURLFilterRule("#\.(jpg|jpeg|gif|png)$# i"); 
$crawler->enableCookieHandling(true);  
$crawler->setTrafficLimit(1000 * 1024); 
$crawler->go(); 
$report = $crawler->getProcessReport(); 

if (PHP_SAPI == "cli") {
  $lb = "\n"; 
} else {
  $lb = "<br />"; 
}

echo "Summary:".$lb; 
echo "Links followed: ".$report->links_followed.$lb; 
echo "Documents received: ".$report->files_received.$lb; 
echo "Bytes received: ".$report->bytes_received." bytes".$lb; 
echo "Process runtime: ".$report->process_runtime." sec".$lb; 

答案 3 :(得分:1)

您可以尝试与管道中的apply功能结合使用:

dput(df)
structure(list(x = c(1L, 1L, 2L, 3L, 3L, 2L, 2L, 1L), y = c(1L, 
2L, 2L, 1L, 1L, 2L, 3L, 3L), z = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 
3L)), .Names = c("x", "y", "z"), class = "data.frame", row.names = c(NA, 
-8L))

df %>% filter(!apply(., 1, function(row) any(row == 1)))
  x y z
1 2 2 2
2 2 3 2

答案 4 :(得分:1)

filter_each中没有dplyr,因此基于rowSums的解决方案是可行的。发布这个非常简单的基本选项,尽管可能更喜欢filter解决方案,以便通过其他操作将输出合并到dplyr管道中。

set.seed(1)
df <- data.frame(x = sample(0:1, 10, replace = TRUE),
                 y = sample(0:1, 10, replace = TRUE))
df[rowSums(df == 1) == 0, ]
  x y
1 0 0
2 0 0

将上面的1修改为任何值都可以使其对其他值进行过滤。此解决方案比基于apply的{​​{1}}解决方案快得多,并且慢于filterdplyr filter

答案 5 :(得分:0)

@George Wood 的答案有效,但 all_vars 已被现有动词中的 if_all 取代,在本例中为 filter 而不是作用域变体 { {1}}。 @George Wood 的答案可以通过将 filter_all 更改为 some_data %>% filter_all(all_vars(.

来更新