【问题标题】:[R]: Flag overlapping time periods[R]:标记重叠时间段
【发布时间】:2018-10-03 19:17:16
【问题描述】:

下面的数据框显示了产品的促销日历,即促销开始的周数、促销的产品以及促销的时长。

我需要一个函数来创建一个标志(通过 PromoID 和 StartWk),指示 Product-WeekNum 组合是否重复,其中 WeekNum 是 (StartWk) 到 (StartWk + Duration)。所以第一行的 WeekNum 是第 5 周和第 6 周(依此类推)。基本上,如果任何 Product-WeekNum 组合重复,则相应的 PromoID-StartWk 组合将被标记。 WeekNum 显示为 R cmets。

如果没有这样的实例,那么函数应该输出一个带有输出字段的空数据帧。

非常需要 - 传递给函数的空数据帧应生成带有输出字段的空数据帧。

如果有帮助,任何给定的 PromoID 在所有实例中都将始终具有相同的产品集和相同的持续时间。

df <- structure(list(PromoID = c("A", "A", "A", "A", "B", "B", "C", 
"C", "D", "A", "A", "E", "E"), Product = c("Flavored", "Original", 
"Flavored", "Original", "Flavored", "Original", "Flavored", "Original", 
"Flavored", "Flavored", "Original", "Energy", "Energy"), StartWk = c(5L, 
5L, 21L, 21L, 30L, 30L, 6L, 6L, 5L, 5L, 5L, 49L, 49L), Duration = c(2L, 
2L, 2L, 2L, 3L, 3L, 1L, 1L, 2L, 2L, 2L, 1L, 1L)), .Names = c("PromoID", 
"Product", "StartWk", "Duration"), class = "data.frame", row.names = c(NA, 
-13L))

   PromoID  Product StartWk Duration
1        A Flavored       5        2 # WeekNum 5, 6
2        A Original       5        2 # WeekNum 5, 6
3        A Flavored      21        2 # WeekNum 21, 22
4        A Original      21        2 # WeekNum 21, 22
5        B Flavored      30        3 # WeekNum 30, 31, 32
6        B Original      30        3 # WeekNum 30, 31, 32
7        C Flavored       6        1 # WeekNum 6
8        C Original       6        1 # WeekNum 6
9        D Flavored       5        2 # WeekNum 5, 6
10       A Flavored       5        2 # WeekNum 5, 6
11       A Original       5        2 # WeekNum 5, 6
12       E   Energy      49        1 # WeekNum 49
13       E   Energy      49        1 # WeekNum 49

预期输出 -

  PromoID StartWk Flag
1       A       5    1
2       C       6    1
3       D       5    1
4       E      49    1

【问题讨论】:

  • 对不起,我不明白:如果 PromoID 和 StartWk 组合有重复,你要一个标志吗?它是如何隐含 Duration 的?产品没用?
  • @s_t 是的,我想要一个标志。您的方案将自动导致重复的 Product-WeekNum,因为 PromoID 在所有实例中始终具有相同的产品集。将此详细信息添加到问题中。
  • 为什么在你的结果中2 A 21 1 没有出现(你的结果是colnames)?
  • PromoID A 适用于第 21 至 22 周,不与任何其他 Product-WeekNum 组合重叠。在帖子中添加了 WeekNum 作为 r cmets。
  • 抱歉问题,但4 E 49 1 与?

标签: r


【解决方案1】:
df %>%
  # Make row for each week of each promotion
  tidyr::uncount(weights = Duration, .id = "wk_no") %>%
  # Show what week is represented by each row
  mutate(CurWk = StartWk + wk_no - 1) %>%
  # How many Promos are there for each product each week?
  add_count(Product, CurWk) %>%
  # Only include overlapping promos
  filter(n > 1) %>%

  # To shape into requested output form, only show one row per overlap
  group_by(PromoID, StartWk) %>%
  summarize(Flag = 1)

输出

# A tibble: 4 x 3
# Groups:   PromoID [?]
  PromoID StartWk  Flag
  <chr>     <int> <dbl>
1 A             5     1
2 C             6     1
3 D             5     1
4 E            49     1

【讨论】:

  • 这太棒了!但是,uncount(df, weights = Duration, .id = "wk_no") %&gt;% mutate(CurWk = StartWk + wk_no - 1) 因空数据框而失败,因为未创建列 wk_no。有没有不使用if else 的优雅方法?
  • 这是一个空数据框供您参考 - df_empty &lt;- data.frame(PromoID = character(), ProductLow = character(), StartWk = integer(), Duration = integer(), stringsAsFactors = F)
  • 不是很优雅,但您可以在df %&gt;% 之后的第一行添加add_row(PromoID = "", Product = "", Duration = 0) %&gt;%。这不会影响正常数据,但会允许空数据集(如果您使用Product 而不是ProductLow)进行无误处理并生成空数据框。
  • 这已经够优雅了!谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-04-13
  • 2016-04-29
  • 2022-01-17
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
相关资源
最近更新 更多