r - 自动记录数据和新列
问题描述
我有一个包含每天销售的产品数量的数据集。然而,数据是以一种奇怪的方式记录的。因此,如果售出的商品数量超过 100,则重置记录器并且售出的商品数量从零开始。我提供了一个记录器如何工作的示例。
df <- data.frame(date = c("2020-01-01", "2020-01-02", "2020-01-03", "2020-01-04", "2020-01-05"),
items_sold = c(10,40,90, 10, 20), items_sold_real = c(10,40,90, 110, 130), items_sold_differene_day = c(NA, 30, 50, 20, 20)
)
所以,我正在尝试创建一个看起来像变量 items_sold_real 的新变量。我想知道您是否知道这里有什么好的解决方案。
谢谢,
解决方案
逻辑:
i
如果当天售出的商品数量低于 ,我们检测到已售出的商品已重置i-1
。(请注意,只有当每天的销售数量最多可以达到 99 个单位时,这才是正确的)。- 如果我们仍然没有超过 100,那么我们只是把出售的物品。
- 如果我们超过 100,我们必须将售出物品的累计总和乘以 100 乘以我们超过 100 的次数。
代码:
items_sold < lag(items_sold, default=F)
一个值是否低于前一个值的逻辑。cumsum
得到这个逻辑向量的累积和(TRUE=1,FALSE=0)。- 我们按这个新变量 (
id
) 进行分组,以确保cumsum
仅应用于同一组的元素。 - 应用上面提到的公式
( id > 0 ) * cumsum(items_sold) + id * 100 + items_sold * ( id == 0 )
:如果id > 0
加上cumsum
100 乘以id
,如果不把 的值item_sold
。 - 可以使用
diff
函数计算差异。
library(tidyverse)
#### if you're tagged data.frame is wrong
## basically there is no longer a need for the cumsums
## so no need to group thus we drop the id column and directly
df %>%
mutate(items_sold_real= cumsum(items_sold<lag(items_sold, default=F))*100 + items_sold, items_sold_differene_day= c(NA,diff(items_sold_real))) -> df
#### if you want to have a result just like the tagged data.frame
df %>%
mutate(id = cumsum(items_sold < lag(items_sold, default=F))) %>%
group_by(id) %>%
mutate(items_sold_real= ( id > 0 ) * cumsum(items_sold) + id * 100 + items_sold * ( id == 0 ) ) %>%
ungroup %>% select(-id) %>%
mutate(items_sold_differene_day= c(NA, diff(items_sold_real))) -> df
identical(df, tibble(df.result))
#> TRUE
df
# A tibble: 5 x 4
date items_sold items_sold_real items_sold_differene_day
<fct> <dbl> <dbl> <dbl>
1 2020-01-01 10 10 NA
2 2020-01-02 40 40 30
3 2020-01-03 90 90 50
4 2020-01-04 10 110 20
5 2020-01-05 20 130 20
数据
df <- data.frame(date = c("2020-01-01", "2020-01-02", "2020-01-03", "2020-01-04", "2020-01-05"),
items_sold = c(10,40,90, 10, 20))
df.result <- data.frame(date = c("2020-01-01", "2020-01-02", "2020-01-03", "2020-01-04", "2020-01-05"),
items_sold = c(10,40,90, 10, 20),
items_sold_real = c(10,40,90, 110, 130),
items_sold_differene_day = c(NA, 30, 50, 20, 20)
)
推荐阅读
- python - 在装饰器中通过别名调用函数
- jquery - 通过jquery克隆表并将其数据插入数据库
- c++ - 在 C++11 Lambda 中绑定 RValue 引用
- ssh - Ansible 如何在 ansible 2.7.x 之前忽略无法访问的主机
- apache-spark - 当我们尝试在 sbt 文件中使用 cloudera 上游版本时,sbt 程序集构建失败
- html - 导航栏对齐
- android - 实例化许多相似布局时如何优化性能?
- python - 迭代和连接 2 个列表占用了大量内存
- node.js - 调试热情测试用例时无法在vscode中的src文件夹内命中断点
- r - 在 R 函数代码中找不到语法错误