在dplyr::mutate中,使用any()和|的区别是什么?

7

当我在 dplyr::mutate() 中比较列时,为什么应该使用 | 而不是 any()

它们为什么会返回不同的结果呢?

例如:

library(tidyverse)
df  <- data_frame(x = rep(c(T,F,T), 4), y = rep(c(T,F,T, F), 3), allF  = F, allT = T)

 df %>%
     mutate( 
          withpipe = x | y # returns expected results by row
        , usingany = any(c(x,y)) # returns TRUE for every row
     )

这里发生了什么?为什么我要使用一种比较值的方式而不是另一种?

2
你的代码无法运行 - 必须是某个地方缺少了括号。 - Spacedman
这就像是向量化中+sum的区别一样。相关且稍微复杂的是:|||之间的区别 - alistaire
代码示例中的拼写错误已经修正。 - crazybilly
3个回答

5
两者的区别在于答案的计算方式:
- 对于竖线 |,元素按行进行比较,并使用布尔逻辑返回正确的值。在上面的例子中,每个x和y对都会相互比较,并为每个对返回一个逻辑值,从而得到12个不同的答案,一个针对数据框中每一行的答案。 - 另一方面,any() 查看整个向量并返回单个值。在上面的例子中,计算新的usingany列的 mutate 行基本上是这样做的:any(c(df$x, df$y)),它将返回TRUE,因为df$xdf$y中至少有一个TRUE值。然后将该单个值分配给数据框的每一行。
您可以通过使用数据框中的其他列来查看此操作:
df %>% 
    mutate(
        usingany = any(c(x,y)) # returns all TRUE
      , allfany  = any(allF)   # returns all FALSE because every value in df$allF is FALSE
    )

回答何时使用哪个符号:当你想逐行比较元素时,请使用 |。当你想要有关整个数据框的通用答案时,请使用 any()

简而言之,在使用 dplyr::mutate() 时,通常会使用 |


3
你也可以使用 rowwise()
df  <- data_frame(x = rep(c(T,F,T), 4), y = rep(c(T,F,T, F), 3), allF  = F, allT = T)

 df %>%
     rowwise() %>%
     mutate(x_or_y = any(x,y))

输出:

# A tibble: 12 x 5  
    x     y     allF  allT  x_or_y  
    <lgl> <lgl> <lgl> <lgl> <lgl>   
  1 TRUE  TRUE  FALSE TRUE  TRUE   
  2 FALSE FALSE FALSE TRUE  FALSE  
  3 TRUE  TRUE  FALSE TRUE  TRUE   
  4 TRUE  FALSE FALSE TRUE  TRUE   
  5 FALSE TRUE  FALSE TRUE  TRUE   
  6 TRUE  FALSE FALSE TRUE  TRUE   
  7 TRUE  TRUE  FALSE TRUE  TRUE   
  8 FALSE FALSE FALSE TRUE  FALSE  
  9 TRUE  TRUE  FALSE TRUE  TRUE  
 10 TRUE  FALSE FALSE TRUE  TRUE  
 11 FALSE TRUE  FALSE TRUE  TRUE  
 12 TRUE  FALSE FALSE TRUE  TRUE  

1

TL;DR (更新): 在使用dplyr进行逐行操作时,if_anyany()最干净的替代品。请参见下文。

您可以同时使用或运算符|any()

比较&all()时也是一样的。

正如建议的那样,您必须考虑到|是矢量化的,而any()则不是

为了以相同的方式使用any(),您必须按行对数据进行分组,这样您就可以调用与any(current_row)等效的函数。这可以通过purrr::pmapdplyr::rowwise来完成。

但是,dplyr::if_any看起来更加简洁。

请参见下面的代码以比较所有方法:

df%>%mutate(
    row_OR=x|y,
    row_pmap_any=pmap_lgl(select(.,c(x,y)), any),
    with_if_any = if_any(c(x,y)))%>%
    rowwise()%>%
    mutate(
    row_rowwise_any=any(c_across(c(x,y))))

# A tibble: 12 × 8
# Rowwise: 
   x     y     allF  allT  row_OR row_pmap_any with_if_any row_rowwise_any
   <lgl> <lgl> <lgl> <lgl> <lgl>  <lgl>        <lgl>       <lgl>          
 1 TRUE  TRUE  FALSE TRUE  TRUE   TRUE         TRUE        TRUE           
 2 FALSE FALSE FALSE TRUE  FALSE  FALSE        FALSE       FALSE          
 3 TRUE  TRUE  FALSE TRUE  TRUE   TRUE         TRUE        TRUE           
 4 TRUE  FALSE FALSE TRUE  TRUE   TRUE         TRUE        TRUE           
 5 FALSE TRUE  FALSE TRUE  TRUE   TRUE         TRUE        TRUE           
 6 TRUE  FALSE FALSE TRUE  TRUE   TRUE         TRUE        TRUE           
 7 TRUE  TRUE  FALSE TRUE  TRUE   TRUE         TRUE        TRUE           
 8 FALSE FALSE FALSE TRUE  FALSE  FALSE        FALSE       FALSE          
 9 TRUE  TRUE  FALSE TRUE  TRUE   TRUE         TRUE        TRUE           
10 TRUE  FALSE FALSE TRUE  TRUE   TRUE         TRUE        TRUE           
11 FALSE TRUE  FALSE TRUE  TRUE   TRUE         TRUE        TRUE           
12 TRUE  FALSE FALSE TRUE  TRUE   TRUE         TRUE        TRUE        

所有的方法都可以使用,我没有发现性能上有太大的差异。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接