【问题标题】:(dplyr) Error when using mutate(), case_when() and which()(dplyr) 使用 mutate()、case_when() 和 which() 时出错
【发布时间】:2020-03-25 13:50:47
【问题描述】:

在以下情况下需要有关错误/警告的帮助:

我有一个带有观察日期的数据框和一个此类日期的向量。我想在数据框中创建具有下一个和上一个观察日期的新列。日期向量创建为:

library(glue)

dates = c("201902",
          "201906",
          "201911",
          "202002")

dates = glue("{dates}01")

dates = dates%>%
        as.Date(format = "%Y%m%d")%>%
        sort()

然后我的数据框有这个由dates元素组成的列,称为Date。我希望它创建具有下一个和上一个日期的列,或者如果它是开始/结束则保持相同。我正在使用:

library(dplyr)

my_df = my_df%>%
mutate(First_date = (Date == dates[1]),
       Last_date = (Date == dates[length(dates)]),
       Prev_date = case_when(First_date ~ Date,
                                   TRUE ~ dates[which(dates == Date)-1]),
       Next_date = case_when(Last_date ~ Date,
                                  TRUE ~ dates[which(dates == Date)+1])

示例:如果我有一个包含以下列的数据框:

>my_df$Date
[1] "2019-02-01" "2019-06-01" "2019-11-01" "2020-02-01"

我希望它结束​​:

>my_df$First_date
[1] TRUE FALSE FALSE FALSE
>my_df$Last_date
[1] FALSE FALSE FALSE TRUE
>my_df$Prev_date
[1] "2019-02-01" "2019-02-01" "2019-06-01" "2019-11-01"
>my_df$Next_date
[1] "2019-06-01" "2019-11-01" "2020-02-01" "2020-02-01"

我使用的测试数据框有 6 行,它会抛出这个错误和警告:

Error: `TRUE ~ dates[which(dates == Date) + 1]` must be length 6 or one, not 2
Run `rlang::last_error()` to see where the error occurred.
In addition: Warning messages:
1: In `==.default`(dates, Date) :
  longer object length is not a multiple of shorter object length
2: In `==.default`(dates, Date) :
  longer object length is not a multiple of shorter object length

我认为这一定与在 case_when() 内调用 which() 函数有关,在 mutate() 内,但我还没有设法弄清楚它到底哪里出错了。

第一次来这里提问,如有错误请见谅!

【问题讨论】:

  • 无法复制,因为我不知道RFB_dates 来自哪里...
  • 对不起@broti,我错过了一个错字。已经更正了
  • 我不确定你的最终数据框应该有哪些列:只是Date?还是First_dateLast_datePrev_dateNext_date
  • @broti,我希望它以所有四个新列以及原始列结束。 mutate() 应该这样做,对吧?
  • 那么四列将只有一个值?最好的办法是为您提供所需的输出作为数据框

标签: r date dplyr


【解决方案1】:

好的,这应该可以。首先,你的df:

dates = c("201902",
          "201906",
          "201911",
          "202002")

dates = glue("{dates}01")

dates = dates%>%
        as.Date(format = "%Y%m%d")%>%
        sort()

my_df <- data.frame(Date = dates)

然后,使用shift 函数:

my_df <- my_df %>%
  mutate(First_date = ifelse(Date == dates[1], TRUE, FALSE),
         Last_date = ifelse(Date == dates[length(dates)], TRUE, FALSE),
         Prev_date = shift(dates, n = 1, fill = dates[1]),
         Next_date = shift(dates, n = -1, fill = dates[length(dates)]))
> my_df
        Date First_date Last_date  Prev_date  Next_date
1 2019-02-01       TRUE     FALSE 2019-02-01 2019-06-01
2 2019-06-01      FALSE     FALSE 2019-02-01 2019-11-01
3 2019-11-01      FALSE     FALSE 2019-06-01 2020-02-01
4 2020-02-01      FALSE      TRUE 2019-11-01 2020-02-01

【讨论】:

  • 这听起来像是您尝试将代码应用到具有 6 行的不同数据框 - 尝试使用我发布的代码重新启动。
  • 我注意到这适用于具有 4 个日期观察值的数据框,但不适用于每个日期多次重复的更大数据框。我正在尝试使用您的方法来调整合并。如果它有效,它将非常有帮助!
  • 试着让 dates 向量更长,例如通过dates_new &lt;- rep(dates, 2),并基于data.frame(Date = dates) 构建df。代码仍然可以工作!
  • 这有帮助!我将使用join 函数将此数据框信息带到我正在使用的那个。
  • 我的主要数据框有超过 900 万行。我想直接改变它,但是创建这个辅助 my_df (就像你一样)然后加入应该可以解决问题。
猜你喜欢
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-30
  • 1970-01-01
  • 2019-05-26
相关资源
最近更新 更多