【问题标题】:ifelse() and if else given different results in dplyr mutate() for a time variableifelse() 和 if else 在 dplyr mutate() 中为时间变量给出不同的结果
【发布时间】:2018-11-15 09:07:14
【问题描述】:

假设一个 data.frame 是这样的:

df <- read.table(text = "ID Date Condition
                1 2015/01/01  Yes
                1 2015/01/10  No        
                1 2015/01/15  Yes
                2 2015/02/10  No                                   
                2 2015/03/08  No
                3 2015/01/01  No                                     
                3 2015/04/01  Yes
                3 2015/04/10  No
                3 2015/04/01  Yes
                3 2015/04/10  No", header = TRUE)

我想分别计算每个 ID 的给定日期和第一个日期之间的天数。现在,对于条件始终为“否”的每个 ID,我想在结果列中分配 NA。

这是我的代码:

df %>%
  mutate(Date = as.Date(Date, "%Y/%m/%d")) %>%
  group_by(ID) %>%
  mutate(Temp = Date - first(Date),
         Res1 = ifelse(all(Condition == "No"), NA, Temp),
         Res2 = if(all(Condition == "No")) NA else Temp)

结果:

      ID Date       Condition Temp    Res1 Res2  
   <int> <date>     <fct>     <time> <dbl> <time>
 1     1 2015-01-01 Yes       0         0. 0     
 2     1 2015-01-10 No        9         0. 9     
 3     1 2015-01-15 Yes       14        0. 14    
 4     2 2015-02-10 No        0        NA  <NA>  
 5     2 2015-03-08 No        26       NA  <NA>  
 6     3 2015-01-01 No        0         0. 0     
 7     3 2015-04-01 Yes       90        0. 90    
 8     3 2015-04-10 No        99        0. 99    
 9     3 2015-04-01 Yes       90        0. 90    
10     3 2015-04-10 No        99        0. 99 

我的问题是, ifelse() 给出错误结果的原因是什么,而 if else() 给出了预期的结果?

【问题讨论】:

标签: r dplyr


【解决方案1】:

显然,您不了解ifelse。它与ifelse 根本不同。文档清楚地说“ifelse 返回一个与test 形状相同的值”,在您的示例中这是一个长度为 1 的向量。 mutate 然后回收这个。

这是一个简单的例子:

all(c(TRUE, TRUE))
#[1] TRUE
ifelse(all(c(TRUE, TRUE)), 1:2, 3:4) #test is vector of length 1
#[1] 1
ifelse(c(TRUE, FALSE), 1:2, 3:4) #test is vector of length 2
#[1] 1 4

我鼓励您研究 ifelse 函数的源代码,这应该可以清楚地了解它为什么会这样。

【讨论】:

  • @Roland 谢谢你的解释。我仍在学习 R 的更多理论方面。
  • yesno 的长度不是test 时,更严格的dplyr::if_else 会报错:dplyr::if_else(all(c(TRUE, TRUE)), 1:2, 3:4)
猜你喜欢
  • 2018-03-18
  • 1970-01-01
  • 2020-10-29
  • 2022-12-20
  • 1970-01-01
  • 1970-01-01
  • 2016-11-21
  • 2018-06-24
  • 2020-07-25
相关资源
最近更新 更多