这就是事情。
我拥有相当大的数据集(150万行),代表40,000个客户端以及40个月以上的一些指标,因此数据看起来或多或少是这样的:
CLIENTID| MONTHID| VALUE
--------|--------|-------
client1 | month1 | value1
client1 | month2 | value2
client1 | month3 | value3
client2 | month1 | value4
client2 | month2 | value5
client3 | month1 | value6
client4 | month1 | value7
etc...
并非每个CLIENTID
都包含所有MONTHID
,许多只在几个月内出现。
所以我正在尝试使用它:
我需要提取数据集中所有CLIENTID
个月期间X
的最大总和为VALUE
的{{1}}个{生命期'X
个月
这个X
个月的期限是连续的,即使对于给定的MONTHID
,特定的CLIENTID
没有特定的X
行,我会查看并发月数。
以下是我在心理上对自己进行可视化处理的逻辑细分:
从数据集中提取第一个MONTHID
CLIENTID
句点,并为每个VALUE
和CLIENTID
提取一个数字,以获得该期间每个CLIENTID
的一个数字将其存储为PERIODID
,新功能VALUE
以及我的功能总结MONTHID
。
通过将句点的起始CLIENTID
增加1,循环到每个CLIENTID
的所有句点,并在给定{{1}}的新值大于的情况下替换存储集中的值以前存储的
所以这是我的问题:
首先:这种方法在逻辑上是否有效?我认为它应该可行,但也许在这种情况下可以使用更容易的解决方案
其次,最重要的是:如何在R中实现它?我还在学习R语言,我知道如何对数据进行子集化,总结它们等...但我正在使用像apply / mapply / etcpply(:P)这样的循环函数。
答案 0 :(得分:1)
如果不知道你的数据是什么样的话,测试它有点困难,我不能说它的速度有多快,但这是一个可能的解决方案。
创建样本数据框:
set.seed(123)
df <- data.frame(
CLIENTID = rep(c("a", "b", "c", "d"), each=10),
MONTHID = as.vector(replicate(4, sample(1:40, 10))),
VALUE = sample(100:500, 40, replace = T))
根据您在问题中的说法,对于某些CLIENTID,没有给定MONTHID的条目。我认为这意味着那个月的价值是0?在这种情况下,最简单的方法是拥有一个表示这些零值的数据框,我们可以使用expand.grid
和merge
来创建。
clientmonths <- expand.grid(
CLIENTID = unique(df$CLIENTID),
MONTHID = seq(from=min(df$MONTHID), to=max(df$MONTHID)))
df2 <- merge(clientmonths, df, all = T)
df2$VALUE[is.na(df2$VALUE)] <- 0
在下文中,我使用base-R中的filter
函数创建滚动总和,并使用dplyr包中完全不相关的filter
函数...
library(dplyr)
getPeriodSum <- function(x, period) {
x %>%
mutate(periodSUM = as.vector(stats::filter(VALUE, rep(1, period), sides=1))) %>%
filter(periodSUM == max(periodSUM, na.rm = T)) %>%
select(endMONTH = MONTHID, periodSUM)
}
df2 %>% arrange(MONTHID) %>% group_by(CLIENTID) %>% getPeriodSum(5)
此代码返回一个带有CLIENTID列的数据框,一个包含指定x月期间的最大累计值VALUE的periodSUM列,以及一个包含x月月末结束的MONTHID的endMONTH列。如果存在联系(即,可以通过多个月的序列生成相同的最大值),则每个CLIENTID将有多个行。
我使用值5来查找最多5个月的总数,但您可以将其更改为其他值。