我们有来自触摸屏自动售货机的销售数据。当客户将钱放入机器时,它会启动一个 session ,并使用该机器特有的数字序列对这些 session 进行计数。大多数时候,系统会在适当的时候启动和停止 session 。然而,大约 7% 的情况下,当机器中还有钱可以花时,它会人为地启动一个新 session 。
所以,
session available.spend actual.spend
1 20 20
2 25 17
3 0 8
4 15 15
5 14 7
6 0 7
7 59 50
8 0 9
9 15 15
10 21 21
其中 available.spend
是所有不同列的总和,表示已将钱或优惠券插入机器,而 actual.spend
是所有钱的总和在那次 session 期间花费了。
所以,大多数时候它们彼此相等。然而,在第 2 节中,插入了 25 美元,但只花费了 17 美元。第 3 节显示没有钱可花,但实际花费了 8 美元,这平衡了第一个节。
我想让 R 组合这些 session 并创建一个指示列,告诉我新 session 是组合 session 的结果。
我如何让 R 查看 session 是否平衡,然后,如果不平衡,请检查下一个 session 以查看是否:
- 没有可用的支出;
- 有实际支出;并且,
- 两个 session 的实际支出 == 第一个 session 的可用支出
然后,如果(且仅当)满足所有三个条件,这两个 session 将被合并(使用 session 编号或新的、虚构的 session 编号),并生成一个带有1 显示新 session 是合并其他 session 的结果。
这是我制作的示例的 dput()
:
mydt<- structure(list(session = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), available.spend = c(20,
25, 0, 15, 14, 0, 59, 0, 15, 21), actual.spend = c(20, 17, 8,
15, 7, 7, 50, 9, 15, 21)), .Names = c("session", "available.spend",
"actual.spend"), row.names = c(NA, -10L), class = c("data.table",
"data.frame"), .internal.selfref = <pointer: 0x0000000000300788>)
这是我希望的输出:
session available.spend actual.spend newsess
1 20 20 0
2 25 25 1
4 15 15 0
5 14 14 1
7 59 59 1
9 15 15 0
10 21 21 0
和dput()
:
mynew.dt<- structure(list(session = c(1, 2, 4, 5, 7, 9, 10), available.spend = c(20,
25, 15, 14, 59, 15, 21), actual.spend = c(20, 25, 15, 14, 59,
15, 21), newsess = c(0, 1, 0, 1, 1, 0, 0)), .Names = c("session",
"available.spend", "actual.spend", "newsess"), row.names = c(NA,
-7L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x0000000000300788>)
我一直在尝试在 data.table (数据集非常大)和/或 ifelse 中找到实现此目的的方法,但我不知道如何检查三个条件并且仅在满足时才执行操作所有这三个,同时还删除旧列并创建虚拟变量列。 哇
还有一个问题:这些 session ID 可能(尽管很少发生)发生在一天以上。因此,代码必须查找 data.frame 中的下一行,或者如果它查找按顺序出现的下一个 session ,则需要确保两个 session 的日期匹配。
感谢您的帮助。
最佳答案
如果您的 available.spend
在这些情况下始终为零,您可以使用它对行进行分组(我假设您有时连续有多个这样的 0,否则您可以简单地采用 actual.spend
,将其移动 1,然后将总和返回进行比较):
dt[, list(session = session[1],
available.spend = sum(available.spend),
actual.spend = sum(actual.spend)),
by = cumsum(available.spend != 0)]
# cumsum session available.spend actual.spend
#1: 1 1 20 20
#2: 2 2 25 25
#3: 3 4 15 15
#4: 4 5 14 14
#5: 5 7 59 59
#6: 6 9 15 15
#7: 7 10 21 21
从现在开始,您应该拥有继续操作所需的所有信息。
也许,更一般地说,最好按cumsum(available.spend >=actual.spend)
分组。
关于根据多种条件重新组合销售数据中人为分割的 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22869840/