【问题标题】:Why is my 'if' argument not interpretable as logical为什么我的“如果”论点不能解释为合乎逻辑的
【发布时间】:2021-04-18 21:31:57
【问题描述】:

我正在处理一些数据并尝试进行一些条件过滤。我想编写一个语句来评估一个变量是否等于一个数字(在本例中为 1),如果是,则根据另一列的值进行过滤。结果应该是所有 AtBatPitchSequences == 1 也有 PitchType == "FA"。

  • 请注意,如果 AtBatPitchSequence > 1 则不应被过滤,因此第 4 行应保留在过滤器之后

我的数据(firsttwopitches)如下所示:

  YearID GameID GamePitchSequen~ PAofInning AtBatPitchSeque~ Inning Balls Strikes PitchType
   <dbl> <chr>             <dbl>      <dbl>            <dbl>  <dbl> <dbl>   <dbl>     <chr>
1   2018 DFCBC~                1          1                1      1     0       0        FA
2   2018 DFCBC~                2          1                2      1     1       0        FA
3   2018 DFCBC~                4          2                1      1     0       0        FA
4   2018 DFCBC~                5          2                2      1     0       1        SI
5   2018 DFCBC~                8          3                1      1     0       0        FA
6   2018 DFCBC~                9          3                2      1     0       1        FA

为了解决这个问题,我尝试使用 if 语句:

library(tidyverse)

firsttwopitches %>%
  if (AtBatPitchSequence == 1) {
    filter(PitchType == "FA")
  }

但是,这会引发错误和警告:

Error in if (.) AtBatPitchSequence == 1 else { : 
  argument is not interpretable as logical
In addition: Warning message:
In if (.) AtBatPitchSequence == 1 else { :
  the condition has length > 1 and only the first element will be used

我不明白为什么我的论点不能被解释为合乎逻辑的。在我看来,它应该评估 AtBatPitchSequence 是否等于 1,然后转到下一行。另外,警告信息是什么意思?如果通过更正我的 if 语句来处理此警告,请不要担心,但我仍然是新手,并且正在尝试更好地调试我自己的工作。我通读了这个Error in if/while (condition) : argument is not interpretable as logical 问题和其他问题,试图找出我的错误,但没有成功。

非常感谢

【问题讨论】:

    标签: r dplyr data-munging


    【解决方案1】:

    我们可以在filter 中使用&amp; 条件

    library(dplyr)
    firsttwopitches %>%   
       filter(AtBatPitchSequence == 1, PitchType == "FA")
    

    如果我们想保留 'AtBatPitchSequence' 不等于 1 的行,则添加另一个表达式 |

    firsttwopitches %>% 
        filter((AtBatPitchSequence == 1 & PitchType == "FA")|AtBatPitchSequence != 1) 
    

    有两个问题 - 1) if/else 未矢量化,2) 与 {} 的代码阻塞有关,尤其是在管道中使用时 (%&gt;%)。一个相关的问题也是在 tidyverse 函数之外找到列名AtBatPitchSequence,即mutatesummarise 等。在这种情况下,我们还需要指定数据.$AtBatPitchSequence


    错误/警告可以通过内置数据集重现

    data(iris)
    head(iris) %>% 
       if(Species == 'setosa') {
           filter(Petal.Length > 1.5)
        }
    

    if (.) Species == "setosa" else { 中的错误: 论证不能解释为合乎逻辑的 另外:警告信息: 在 if (.) Species == "setosa" else { : 条件的长度 > 1,并且只使用第一个元素

    现在,我们可以通过在 {} 内阻塞来消除错误,但请注意,警告仍然存在,因为 if/else 未矢量化,这也可能给出不正确的输出(以下输出是正确的,但这只是因为只有一行满足 TRUE 条件)

    head(iris) %>% 
        {if(.$Species == 'setosa') {
            filter(., Petal.Length > 1.5)
         }}
    #  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    #1          5.4         3.9          1.7         0.4  setosa
    

    警告信息: 在 if (.$Species == "setosa") { : 条件的长度 > 1,并且只使用第一个元素

    如果我们在filter 中使用多个表达式(, 将生成&amp;

    head(iris) %>% 
        filter(Species == 'setosa', Petal.Length > 1.5)
    #  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    #1          5.4         3.9          1.7         0.4  setosa
    

    【讨论】:

    • 感谢您的回答更有意义。但是,我相信我在这个问题上误导了你。我想保留 AtBatPitchSequence = 2 和 PitchType != FA 的行。例如,我想在示例数据集中保留第 4 行。但是,如果 AtBatPitchSequence = 1 和 PitchType = SI 我希望将其删除
    • @ChrisEwanik 所以,如果它只代表 1,那么 firsttwopitches %&gt;% filter(AtBatPitchSequence == 1 &amp; PitchType == "FA", AtBatPitchSequence != 1)
    • @ChrisEwanik 我更新了帖子。它应该是一个| 条件
    • 我看不到任何错字。一切都如我所愿,再次感谢您!
    猜你喜欢
    • 2020-04-27
    • 2014-05-08
    • 2019-01-20
    • 2015-05-04
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多