【问题标题】:How to get quick summary in data.table with a look-back window?如何通过回顾窗口快速获取 data.table 中的摘要?
【发布时间】:2017-06-22 01:35:39
【问题描述】:

此问题是基于how to get quick summary of count in data.table 的扩展。

同样,这是特征工程的一部分,它根据称为 Col 的列通过回顾特定的时间窗口来总结每个 ID。相同的预处理将应用于测试集。由于数据集很大,基于 data.table 的解决方案可能更受欢迎。

1。使用回顾窗口对变量和值进行汇总

训练输入:

ID   Time        Col   Count 
A    2017-06-05   M      1
A    2017-06-02   M      1
A    2017-06-03   M      1
B    2017-06-02   K      1
B    2017-06-01   M      4

通过应用两天回顾,我们有:

ID   Time          Time-2D   Col   Count
A    2017-06-05   2017-06-03   M      1   #Time-2D by moving time two days back
A    2017-06-02   2017-05-31   M      1
A    2017-06-03   2017-06-01   M      1
B    2017-06-02   2017-05-31   K      1
B    2017-06-01   2017-05-30   M      4

预期输出(计数):

ID   Time          Time-2D   Col_M    Col_K
A    2017-06-05   2017-06-03   1      0     #from 2017-06-03 to 2017-06-05, for user A, there are 0 (sum(count)) of K and 1 (sum(count)) of M. 
A    2017-06-02   2017-05-31   1      0
A    2017-06-03   2017-06-01   2      0     # 2 is because from 06-01 to 06-03, there is two rows in the first table (A    2017-06-02   M      1; A    2017-06-03   M      1) that the count summarization on M is 2. 
B    2017-06-02   2017-05-31   0      1
B    2017-06-01   2017-05-30   4      0

2。计算比例

根据上表, 预期产出(比率):

ID   Time          Time-2D   Col_M    Col_K
A    2017-06-05   2017-06-03   1      0     # 1/sum(1+0)
A    2017-06-02   2017-05-31   1      0
A    2017-06-03   2017-06-01   1      0     #2/sum(2+0)
B    2017-06-02   2017-05-31   0      1
B    2017-06-01   2017-05-30   1      0     # 4/sum(4+0) 

以上用于处理训练数据。对于测试数据集,如果需要映射到 Col_M, Col_K,意思是如果 Col 中出现 S 等其他值,将被忽略。

【问题讨论】:

  • 可能在您的第 1 步中,预期的输出是错误的。不是 2?

标签: r data.table


【解决方案1】:

我想我理解您的要求。您似乎关心观察的顺序,例如,第二个观察Time 是否在第一个观察Time 之前。这没有多大意义,但为了实现这一点,这里有一个高效的 data.table 解决方案。这基本上是由IDColTime 行索引(基本上是外观顺序)进行的 non-equi 连接。之后,只需 dcast 从长转换为宽(就像你之前的问题一样)。请注意,结果是按日期排序的,但我保留了 rowindx 变量,因此您可以使用 setorder 重新排序。另外,我会为您保留比率计算,因为这是非常基本的(提示 - 不要使用循环,它是一个完全矢量化的单行)

library(data.table) #v1.10.4+

## Read the data
DT <- fread("ID   Time        Col   Count 
A    2017-06-05   M      1
A    2017-06-02   M      1
A    2017-06-03   M      1
B    2017-06-02   K      1
B    2017-06-01   M      4")

## Prepare the variables we need for the join
DT[, Time := as.IDate(Time)]
DT[, Time_2D := Time - 2L]
DT[, rowindx := .I]

## Non-equi join, sum `Count` by each join
DT2 <- DT[DT, 
          sum(Count), 
          on = .(ID, Col, rowindx <= rowindx, Time <= Time, Time >= Time_2D),
          by = .EACHI]

## Fix column names (a known issue)
setnames(DT2, make.unique(names(DT2)))

## Long to wide (You can reorder back using `rowindx` and `setorder` function)
dcast(DT2, ID + Time + Time.1 + rowindx ~ Col, value.var = "V1", fill = 0)
#    ID       Time     Time.1 rowindx K M
# 1:  A 2017-06-02 2017-05-31       2 0 1
# 2:  A 2017-06-03 2017-06-01       3 0 2
# 3:  A 2017-06-05 2017-06-03       1 0 1
# 4:  B 2017-06-01 2017-05-30       5 0 4
# 5:  B 2017-06-02 2017-05-31       4 1 0

【讨论】:

  • 有一个快速的问题。您知道如何对列列表进行按列求和吗?即DT2 &lt;- DT[DT, sum(Count), on = .(ID, Col, rowindx &lt;= rowindx, Time &lt;= Time, Time &gt;= Time_2D), by = .EACHI],我们有count 列,以及其他列。
  • 是的,就像您在 data.table 中所做的那样。例如,如果你还有 Count2Count3 cols,你可以简单地这样做:DT2 &lt;- DT[DT, lapply(.SD, sum), .SDcols = c("Count", "Count2", "Count3"),on = .(ID, Col, rowindx &lt;= rowindx, Time &lt;= Time, Time &gt;= Time_2D), by = .EACHI]
  • 谢谢。有用。我以前尝试过使用 .SDcols,但是,它与 keyby 有 conflix。 by=.EACHIkeyby=.EACHI有什么区别
  • 我不确定您所说的“conflix”是什么意思。 bykeyby 之间的区别在于 by 使结果无序,而 keyby 添加一个键(根据指定的列)并因此按指定的列对整个数据进行排序。
【解决方案2】:

你可以试试

dt <- fread("ID   Time          Time-2D   Col   Count
        A    2017-06-05   2017-06-03   M      1   
        A    2017-06-02   2017-05-31   M      1
        A    2017-06-03   2017-06-01   M      1
        B    2017-06-02   2017-05-31   K      1
        B    2017-06-01   2017-05-30   M      4") 
dt1 <- dcast(dt, ID+Time+`Time-2D`~Col, value.var = c("Count"))
dt1[, K := ifelse(is.na(K), 0, K)]
dt1[, M := ifelse(is.na(M), 0, M)]

   ID       Time    Time-2D K M
1:  A 2017-06-02 2017-05-31 0 1
2:  A 2017-06-03 2017-06-01 0 1
3:  A 2017-06-05 2017-06-03 0 1
4:  B 2017-06-01 2017-05-30 0 4
5:  B 2017-06-02 2017-05-31 1 0

dt1[, Col_K := K/(K+M)]
dt1[, Col_M := M/(K+M)]

    ID       Time    Time-2D K M Col_K Col_M
1:  A 2017-06-02 2017-05-31 0 1     0     1
2:  A 2017-06-03 2017-06-01 0 1     0     1
3:  A 2017-06-05 2017-06-03 0 1     0     1
4:  B 2017-06-01 2017-05-30 0 4     0     1
5:  B 2017-06-02 2017-05-31 1 0     1     0

也许您可以合并最后两行。像

dt1[, `:=`()]

【讨论】:

  • 我认为缺少聚合和比率步骤。
  • 实际上,您在上面发布的预期输出不包含聚合和比率。或者,也许我误解了你的问题。你能解释更多并补充你的问题吗?
  • 详细说明您的第 2 步
  • 评论中有解释。例如,# 4/sum(4+0),这意味着 4/4=1
  • 其实我看不懂# 2 is because from 06-01 to 06-03, there is two M occurs in A. 也许你需要解释清楚,描述清楚
猜你喜欢
  • 1970-01-01
  • 2019-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-03
  • 1970-01-01
  • 2019-04-16
  • 1970-01-01
相关资源
最近更新 更多