r data.table:关于' by'的两个问题。 ((1)=。我和(2)='顺序由')

时间:2015-07-02 14:29:50

标签: r data.table

我有两个关于' by'在包data.table。

1)如何将.I与它一起使用?例如,假设我们的用户在一天中的某些时间进入商店,我想要一个变量告诉我“我们看到的时间是多长时间”这个用户?'' ...即

> library(data.table)
> dt = data.table(visitorId = c(1,2,1,2,1), daytime=c(1,4,7,9,11))
> dt
       visitorId daytime
1:         1        1
2:         2        4
3:         1        7
4:         2        9
5:         1       11

所需的解决方案将产生

       visitorId daytime  howOftenHaveYouBeenHere
1:         1        1              1
2:         2        4              1
3:         1        7              2
4:         2        9              2
5:         1       11              3

现在我玩了.I的data.table,并没有给我任何我想要的东西:我(:-)抱歉,无法抗拒)预计会工作dt = dt[, howOftenHaveYouBeenHere := .I, by=visitorId]但是这给了

       visitorId daytime  howOftenHaveYouBeenHere
1:         1        1              1
2:         2        4              1
3:         1        7              2
4:         2        9              2
5:         1       11              1 <---- not a 3 here!!!

我使用

使其工作
dt = dt[, stupid := 1]
dt = dt[, session := cumsum(stupid), by=visitorId]; print(dt)

但这样做感觉不太好......

2)如何确保data.table按时间计算会话次数,即到现在为止

a)相应地订购表格

b)执行&#39;语句

是正确的方式,还是可以“走私”进入&#39; SQL&#39; ORDER BY&#39;某处?

例如:如果我们从上面反转数据表 dt = data.table(visitorId = c(1,2,1,2,1), daytime=c(11,9,7,4,1)) 然后

dt = dt[, stupid := 1]
dt = dt[, session := cumsum(stupid), by=visitorId]; print(dt)

没有给出所需的结果。我们可以通过这样做来解决它:

dt = data.table(visitorId = c(1,2,2,1,1), dayTime=c(11,9,4,7,1))
dt = dt[order(dayTime, decreasing=FALSE)]
dt = dt[, stupid := 1]
dt = dt[, howOftenHaveYouBeenHere := cumsum(stupid), by=visitorId]

但是有没有正确的&#39;这样做的方式?即是否保证订单在执行by-statement时保持固定?

谢谢: - )

FW

1 个答案:

答案 0 :(得分:4)

.I是整个表格中的计数器 - 不是按组。我们需要构建一个组内计数器:

dt[, seqobs := seq_along(.I), by=visitorId]
# or...
dt[, seqobs := seq_len(.N), by=visitorId]
# or...
dt[, seqobs := 1:.N, by=visitorId]

#    visitorId daytime seqobs
# 1:         1       1      1
# 2:         2       4      1
# 3:         1       7      2
# 4:         2       9      2
# 5:         1      11      3

这比初始化一列并获取累积总和更容易。

为了理解这一点,需要在每个组中按daytime对数据进行排序。如果不是......

# example of an out-of-order table
dt2 <- dt[sample(.N)]

dt2[order(daytime), seqobs := seq(.N), by=visitorId]

顺便说一句,如果您想更改data.table的顺序,请使用setorder函数。

(在data.table软件包的下一个版本1.9.8中,会有一个小快捷方式dt[, seqobs := rowidv(visitorId)]。我正在编写此笔记,以便稍后更新答案。)