问题描述
我在 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)
我试图生成 Date
和 endDate
之间的日期序列作为每一行。我正在使用下面的代码来生成序列
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