【问题标题】:Warning message: the condition has length > 1 and only the first element will be used警告消息:条件的长度 > 1,并且只会使用第一个元素
【发布时间】:2020-05-23 08:13:18
【问题描述】:

以下是我在 R 中的代码。我使用 dplyr 包按 ID 和日期排列数据,并尝试使用 mutate() 创建新列 SD。在 SD 列中,SD 列中的结果有一些标准,因此我使用了 if() 和 if else() 函数,但有警告消息。

library(dplyr)

ID<-c("A01","A02","A03","A01","A01","A03","A02")
SA<-c(50,100,50,100,150,100,20)
a<-c("01/01/2012","01/01/2011","01/01/2012","01/01/2011","01/01/2013","01/01/2013","01/01/2012")
Date<-as.Date(a, format = "%d/%m/%Y")
df <- data.frame(ID,Date,SA)

start_date = as.Date("01/01/2012", format = "%d/%m/%Y")
end_date = as.Date("31/03/2012", format = "%d/%m/%Y")

df %>% 
  arrange(ID,Date) %>% 
  group_by(ID) %>% 
  mutate(start_date=start_date,
         end_date=end_date,
         period=as.numeric(end_date - start_date + 1),
         SD = if(Date <= start_date & Date + 365 >= end_date) {1} 
              else if(Date + 365 <= start_date | Date >= end_date) {0}
              else if(Date <= start_date & Date + 365 <= end_date) {(Date + 365 - start_date + 1)/period}
              else if(Date >= start_date & Date + 365 >= end_date) {(end_date - Date + 1)/period})

但是,有如下警告消息。我该如何解决?

"Warning messages:
1: In if (Date <= start_date & Date + 365 >= end_date) { :
  the condition has length > 1 and only the first element will be used
2: In if (Date + 365 <= start_date | Date >= end_date) { :
  the condition has length > 1 and only the first element will be used
3: In if (Date <= start_date & Date + 365 >= end_date) { :
  the condition has length > 1 and only the first element will be used
4: In if (Date + 365 <= start_date | Date >= end_date) { :
  the condition has length > 1 and only the first element will be used
5: In if (Date <= start_date & Date + 365 >= end_date) { :
  the condition has length > 1 and only the first element will be used"

【问题讨论】:

  • 嗨!如果在 mutate 中这样,我不会使用。为什么不坚持使用 ifelse 甚至更好的 case_when()?此外,您的示例不可重现,您正在使用 startdate 和 enddate 但它们不在您的 df 中。
  • 但我认为 ifelse 只能在 2 个条件下使用。我有 4 个条件。
  • 您可以在 ifelse 中使用 ifelse,但这很丑陋/不可取。这就是为什么我会建议 case_when SD = case_when(Date &lt;= start_date &amp; Date + 365 &gt;= end_date ~1 , Date + 365 &lt;= start_date | Date &gt;= end_date ~0, Date &lt;= start_date &amp; Date + 365 &lt;= end_date ~(Date + 365 - start_date + 1)/period, Date &gt;= start_date &amp; Date + 365 &gt;= end_date~ (end_date - Date + 1)/period)) 但由于您的示例不起作用(它没有开始或结束日期),我无法为您提供正确的代码

标签: r if-statement dplyr


【解决方案1】:

这是ifelse的解决方案

df %>% 
  arrange(ID,Date) %>% 
  group_by(ID) %>% 
  mutate(start_date=start_date,
         end_date=end_date,
         period=as.numeric(end_date - start_date + 1),
         SD = ifelse(Date <= start_date & Date + 365 >= end_date,
                     1, 
                     ifelse(Date + 365 <= start_date | Date >= end_date,
                            0, 
                            ifelse(Date <= start_date & Date + 365 <= end_date,
                                   (Date + 365 - start_date + 1)/period,
                                   (end_date - Date + 1)/period)))
  )

ifelse 有 3 个条目,条件、条件 ==TRUE 时发生的情况和条件 ==FALSE 时发生的情况。您可以链接ifelse 命令来检查多个条件,就像我在这里所做的那样。

case_when 可能是更易读的选项。

【讨论】:

    【解决方案2】:

    case_when 的解决方案(假设开始日期是日期的最小值,结束日期是日期的最大值)

    df %>% 
      arrange(ID,Date) %>% 
      group_by(ID) %>% 
      mutate(start_date=min(Date),
             end_date=max(Date),
             period= as.numeric(end_date - start_date + 1) ,
             SD = case_when(Date <= start_date & Date + 365 >= end_date ~ 1 ,
                            Date + 365 <= start_date | Date >= end_date ~0,
                            Date <= start_date & Date + 365 <= end_date ~ as.numeric((Date + 365 - start_date + 1)/period),
                            Date >= start_date & Date + 365 >= end_date~ as.numeric((end_date - Date + 1)/period)))
    

    注意:您错过了 Date > start_date 和 Date

    【讨论】:

    • 我的 start_date 和 end_date 如下所示。 start_date = as.Date("01/01/2012", format = "%d/%m/%Y") end_date = as.Date("31/03/2012", format = "%d/%m/ %Y") 感谢您的 case_when,它有效!非常感谢!
    • 那你需要 group_by 做什么?在此示例中,我没有看到按组划分的突变。
    猜你喜欢
    • 1970-01-01
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多