在 R 中的数据框中的列中创建日期序列

问题描述

我在 R 中有一个数据框,如下所示:

df <- data.frame("Type" = c("Item A","Item B"),"Frequency" = c("Quarterly","Other"),"Date" = as.Date(c("2021-02-05","2021-05-05")),"endDate" = as.Date("2021-12-12"),stringsAsFactors = F)

我试图生成 DateendDate间的日期序列作为每一行。我正在使用下面的代码生成序列

df <- df %>%
  dplyr::mutate(id = 1:nrow(df),deliveryDate = ifelse(
    df$Frequency == "Quarterly",list(seq(as.Date(df$Date),as.Date(df$endDate),by = "3 month")),ifelse(df$Frequency == "Monthly",by = "month")),ifelse(df$Frequency %in% c("Other"),as.Date(df$Date),df$Date)))) %>%
  tidyr::unnest(deliveryDate) %>%
  dplyr::group_by(Type) %>%
  dplyr::mutate(deliveryNumber = row_number()) %>%
  dplyr::select(deliveryNumber,Type,Frequency,deliveryDate) %>%

为了更具描述性,将根据类型的频率生成日期序列。因此,为了处理这种情况,我使用了 dplyr::mutate()

但我收到如下错误

Error: Problem with `mutate()` input `deliveryDate`.
x 'from' must be of length 1
ℹ Input `deliveryDate` is `ifelse(...)`.

谁能帮我在 R 中解决这个问题?提前致谢!!!

解决方法

这是一种方法。不清楚您想要“其他”与“月”相反的内容,因此我在此处将其设置为“周”。

请注意,使用 mutate() 时不需要引用数据框,因为函数中调用的所有内容都设置为数据框的环境。此外,考虑使用 case_when() 而不是使用嵌套的 ifelse() 调用。

library(tidyverse)

df %>% 
  mutate(Frequency2 = case_when(Frequency == "Quarterly" ~ "3 month",Frequency == "Month" ~ "month",TRUE ~ "week")) %>% 
  group_by(Type,Frequency2) %>% 
  nest() %>% 
  mutate(middates = map2(data,Frequency2,~ seq.Date(min(.x$Date),max(.x$endDate),by = .y))) %>% 
  unnest(c(data,middates)) %>% 
  ungroup()

# A tibble: 36 x 6
   Type   Frequency Frequency2 Date       endDate    middates  
   <chr>  <chr>     <chr>      <date>     <date>     <date>    
 1 Item A Quarterly 3 month    2021-02-05 2021-12-12 2021-02-05
 2 Item A Quarterly 3 month    2021-02-05 2021-12-12 2021-05-05
 3 Item A Quarterly 3 month    2021-02-05 2021-12-12 2021-08-05
 4 Item A Quarterly 3 month    2021-02-05 2021-12-12 2021-11-05
 5 Item B Other     week       2021-05-05 2021-12-12 2021-05-05
 6 Item B Other     week       2021-05-05 2021-12-12 2021-05-12
 7 Item B Other     week       2021-05-05 2021-12-12 2021-05-19
 8 Item B Other     week       2021-05-05 2021-12-12 2021-05-26
 9 Item B Other     week       2021-05-05 2021-12-12 2021-06-02
10 Item B Other     week       2021-05-05 2021-12-12 2021-06-09
# ... with 26 more rows
,

您应该考虑命名向量:

图书馆(tidyverse)

vec<-c(Quarterly = "3 months",Other = "month")

df %>% 
   rowwise() %>%
   mutate(deliveryDate = list(seq(Date,endDate,by = vec[Frequency]))) %>%
   unnest(deliveryDate)

# A tibble: 12 x 5
   Type   Frequency Date       endDate    deliveryDate
   <chr>  <chr>     <date>     <date>     <date>      
 1 Item A Quarterly 2021-02-05 2021-12-12 2021-02-05  
 2 Item A Quarterly 2021-02-05 2021-12-12 2021-05-05  
 3 Item A Quarterly 2021-02-05 2021-12-12 2021-08-05  
 4 Item A Quarterly 2021-02-05 2021-12-12 2021-11-05  
 5 Item B Other     2021-05-05 2021-12-12 2021-05-05  
 6 Item B Other     2021-05-05 2021-12-12 2021-06-05  
 7 Item B Other     2021-05-05 2021-12-12 2021-07-05  
 8 Item B Other     2021-05-05 2021-12-12 2021-08-05  
 9 Item B Other     2021-05-05 2021-12-12 2021-09-05  
10 Item B Other     2021-05-05 2021-12-12 2021-10-05  
11 Item B Other     2021-05-05 2021-12-12 2021-11-05  
12 Item B Other     2021-05-05 2021-12-12 2021-12-05  
,

使用complete

df %>% group_by(Type) %>% mutate(DeliveryDate = Date,Frequency = case_when(Frequency %in% "Quarterly"~ "quarter",Frequency %in% "Monthly" ~ "month",Frequency %in% "Weekly" ~ "week",TRUE ~ "month")) %>%
  complete(DeliveryDate = seq.Date(Date,by = Frequency)) %>%
  fill(Frequency,Date,endDate)

# A tibble: 12 x 5
# Groups:   Type [2]
   Type   DeliveryDate Frequency Date       endDate   
   <chr>  <date>       <chr>     <date>     <date>    
 1 Item A 2021-02-05   quarter   2021-02-05 2021-12-12
 2 Item A 2021-05-05   quarter   2021-02-05 2021-12-12
 3 Item A 2021-08-05   quarter   2021-02-05 2021-12-12
 4 Item A 2021-11-05   quarter   2021-02-05 2021-12-12
 5 Item B 2021-05-05   month     2021-05-05 2021-12-12
 6 Item B 2021-06-05   month     2021-05-05 2021-12-12
 7 Item B 2021-07-05   month     2021-05-05 2021-12-12
 8 Item B 2021-08-05   month     2021-05-05 2021-12-12
 9 Item B 2021-09-05   month     2021-05-05 2021-12-12
10 Item B 2021-10-05   month     2021-05-05 2021-12-12
11 Item B 2021-11-05   month     2021-05-05 2021-12-12
12 Item B 2021-12-05   month     2021-05-05 2021-12-12