r - R在data.table中创建嵌套滚动列表
问题描述
我有一个dt
具有以下结构的 data.table:
country calendar_date net_revenue
US 2018-05-17 3.5,28.0, 3.5, 3.5,10.5, 5.6,...
US 2018-05-18 3.5,102.9,229.6, 8.4, 3.5, 2.1,...
US 2018-05-19 3.5,13.3,35.0, 7.0,52.5, 3.5,...
US 2018-05-20 3.85, 7.00,58.10, 7.00, 3.50, 7.00,...
US 2018-05-21 17.5, 3.5, 3.5,10.5, 1.4, 3.5,...
US 2018-05-22 5.60000, 3.50000,17.50000, 3.50000, 2.10000, 7.05516,...
US 2018-05-23 17.50000,16.10000,58.01507, 2.80000, 5.60000, 3.50000,...
US 2018-05-24 3.50000,26.72765, 3.50000,12.60000, 3.50000, 3.50000,...
US 2018-05-25 2.1,308.0, 2.1, 2.1, 3.5, 3.5,...
US 2018-05-26 2.10000, 3.50000,88.90000, 3.50000, 3.50000, 7.75859,...
US 2018-05-27 5.22087,17.50000, 5.60000, 3.50000, 7.00000, 7.00000,...
US 2018-05-28 3.5,35.0, 1.4, 3.5, 7.0,28.0,...
US 2018-05-29 9.1, 7.0,23.1, 1.4, 1.4, 9.1,...
US 2018-05-30 7.7, 2.1,10.5,15.4,65.1, 3.5,...
其中列net_revenue
是嵌套列表:
str(dt)
Classes ‘data.table’ and 'data.frame': 14 obs. of 3 variables:
$ country : chr "US" "US" "US" "US" ...
$ calendar_date: chr "2018-05-17" "2018-05-18" "2018-05-19" "2018-05-20" ...
$ net_revenue :List of 14
..$ : num 3.5 28 3.5 3.5 10.5 5.6 14 2.1 3.5 28 ...
..$ : num 3.5 102.9 229.6 8.4 3.5 ...
..$ : num 3.5 13.3 35 7 52.5 3.5 7 35 3.5 19.6 ...
..$ : num 3.85 7 58.1 7 3.5 7 1.4 3.5 34.3 2.1 ...
..$ : num 17.5 3.5 3.5 10.5 1.4 3.5 15.4 26.6 10.5 5.6 ...
..$ : num 5.6 3.5 17.5 3.5 2.1 ...
..$ : num 17.5 16.1 58 2.8 5.6 ...
..$ : num 3.5 26.7 3.5 12.6 3.5 ...
..$ : num 2.1 308 2.1 2.1 3.5 ...
..$ : num 2.1 3.5 88.9 3.5 3.5 ...
..$ : num 5.22 17.5 5.6 3.5 7 ...
..$ : num 3.5 35 1.4 3.5 7 28 3.5 3.5 3.5 7 ...
..$ : num 9.1 7 23.1 1.4 1.4 9.1 7 2.1 5.6 2.1 ...
..$ : num 7.7 2.1 10.5 15.4 65.1 3.5 28 3.5 24.5 19.6 ...
- attr(*, ".internal.selfref")=<externalptr>
我需要做的是创建一个列,该列将每个by的 7 个最后日期net_revenue_roll
的列表连接起来- 即“rolling(ly)”将一个函数(或者或)应用于 data.table 中的嵌套列表。net_revenue
calendar_date
country
list
c
参考类似的问题(最后的链接),到目前为止,我尝试了 3 种方法,但它们似乎都不适用于这个特定问题:
### Option 1 - rollapplyr
dt[, net_revenue_roll := zoo::rollapplyr (net_revenue, 7L, list), by = c('country')]
### Option 2 - lapply + .SD
dt[, net_revenue_roll := lapply (.SD, function (x) {list (shift(x, 0L:6L, type = 'lag'))}), by = c('country'), .SDcols = c('net_revenue')]
### Option 3 - Reduce + .SD
dt[, net_revenue_roll := Reduce (list, shift(.SD, 0L:6L, type = 'lag')), by = c('country'), .SDcols = c('net_revenue')]
我怀疑我对应用函数的顺序做出了一些错误的假设,但我找不到错误。有什么建议么?
解决方案
使用DT
末尾的注释将每个列表元素转换为字符串,使用rollapplyr
并转换回来。
library(data.table)
library(zoo)
DT[, ch := sapply(net_revenue, toString)][,
ch := rollapplyr(ch, 7, toString, partial = TRUE), by = "country"][,
net_revenue := lapply(strsplit(ch, ","), type.convert)][,
ch:=NULL]
笔记
可重现形式的输入是:
library(data.table)
Lines <- "
country calendar_date net_revenue
US 2018-05-17 3.5,28.0, 3.5, 3.5,10.5, 5.6
US 2018-05-18 3.5,102.9,229.6, 8.4, 3.5, 2.1
US 2018-05-19 3.5,13.3,35.0, 7.0,52.5, 3.5
US 2018-05-20 3.85, 7.00,58.10, 7.00, 3.50, 7.00
US 2018-05-21 17.5, 3.5, 3.5,10.5, 1.4, 3.5
US 2018-05-22 5.60000, 3.50000,17.50000, 3.50000, 2.10000, 7.05516
US 2018-05-23 17.50000,16.10000,58.01507, 2.80000, 5.60000, 3.50000
US 2018-05-24 3.50000,26.72765, 3.50000,12.60000, 3.50000, 3.50000
US 2018-05-25 2.1,308.0, 2.1, 2.1, 3.5, 3.5
US 2018-05-26 2.10000, 3.50000,88.90000, 3.50000, 3.50000, 7.75859
US 2018-05-27 5.22087,17.50000, 5.60000, 3.50000, 7.00000, 7.00000
US 2018-05-28 3.5,35.0, 1.4, 3.5, 7.0,28.0
US 2018-05-29 9.1, 7.0,23.1, 1.4, 1.4, 9.1
US 2018-05-30 7.7, 2.1,10.5,15.4,65.1, 3.5"
L <- trimws(readLines(textConnection(Lines)))
L <- sub("\\s+", ";", L)
L <- sub("\\s+", ";", L)
DF <- read.table(text = L, header = TRUE, sep = ";", as.is = TRUE)
DF$net_revenue <- lapply(strsplit(DF$net_revenue, ","), type.convert)
DT <- as.data.table(DF)
推荐阅读
- php - Laravel:在发送电子邮件之前执行查询
- parsing - 如何在 Prolog 中使用 DCG
- .net - 如何使用 MOQ 模拟 User.Identity?
- java - 不允许将数组初始值设定项作为方法参数传递
- android - 在 Android 中以编程方式创建新的 RelativeLayout
- javascript - 有没有另一种方法将数据推送到js中的数组
- html - 如何使用 flex 平均分配保证金?
- swift - 无论如何不使用 optional 进行条件赋值吗?
- django - 如何反转名称中带有连字符的 URL?
- python-3.x - 如何在python3中平滑一条线?