我有一个如下所示的数据集:
shop_id,item_id,time,value
150,1,2015-07-10,3
150,1,2015-07-11,5
150,1,2015-07-13,2
150,2,2015-07-10,15
150,2,2015-07-12,12
在每个组中,由" shop_id和" item_id"定义,缺少日期。
我希望将这个不规则的时间序列扩展为每个组内的常规连续日期:
shop_id,item_id,time,value
150,1,2015-07-10,3
150,1,2015-07-11,5
150,1,2015-07-12,0 # <~~ added
150,1,2015-07-13,2
150,2,2015-07-10,15
150,2,2015-07-11,0 # <~~ added
150,2,2015-07-12,12
对于添加的日期,相应的值应为零。我已经阅读了非常相似的问题(使用R或SQL合并),但我见过的大多数解决方案并不涉及GROUP BY。
基本上我可以访问SQL数据库/我可以导出为CSV,最好在C#中进行操作。希望找到可以进行此类数据操作但无法找到任何数据库的C#库。
感谢任何建议或帮助!
答案 0 :(得分:9)
您可以使用data.table
中的R
。假设'time'列是'Date'类,
library(data.table)#v1.9.5+
DT1 <- setDT(df1)[, list(time=seq(min(time), max(time), by ='day')),
by =.(shop_id, item_id)]
setkeyv(df1, names(df1)[1:3])[DT1][is.na(value), value:=0]
# shop_id item_id time value
#1: 150 1 2015-07-10 3
#2: 150 1 2015-07-11 5
#3: 150 1 2015-07-12 0
#4: 150 1 2015-07-13 2
#5: 150 2 2015-07-10 15
#6: 150 2 2015-07-11 0
#7: 150 2 2015-07-12 12
在devel版本中,您也可以在不设置“密钥”的情况下执行此操作。安装devel版本的说明是here
df1[DT1, on =c('shop_id', 'item_id', 'time')][is.na(value), value:=0]
# shop_id item_id time value
#1: 150 1 2015-07-10 3
#2: 150 1 2015-07-11 5
#3: 150 1 2015-07-12 0
#4: 150 1 2015-07-13 2
#5: 150 2 2015-07-10 15
#6: 150 2 2015-07-11 0
#7: 150 2 2015-07-12 12
或者正如@Arun建议的那样,更有效的选择是
DT1[, value := 0L][df1, value := i.value, on = c('shop_id', 'item_id', 'time')]
DT1
答案 1 :(得分:3)
这是一个基于Sql的解决方案
首先你需要一个dates
表
日期表查询。请注意,这将在您的数据库中创建物理表。
;with cte as
(
select cast('2000-01-01' as datetime) as Dates -- Start date
union all
select dateadd(MM,1,Dates)
from cte
where Dates < '2099-12-01' -- End date
)
select *
INTO Date_table
from CTE
然后,您需要left outer join
使用Date_table
的{{1}}来获取缺少的日期。
SELECT A.shop_id,
A.item_id,
DT.dates,
Isnull(Y.value, 0)
FROM date_table DT
CROSS JOIN(SELECT DISTINCT shop_id,
item_id
FROM yourtable) A
LEFT OUTER JOIN yourtable Y
ON t.[time] = DT.dates
AND A.shop_id = Y.shop_id
AND A.item_id = Y.item_id
答案 2 :(得分:0)
以下是来自fill_by_value
的{{1}}的解决方案:
padr
<强>结果:强>
library(dplyr)
library(tidyr)
library(padr)
df %>%
mutate(time = as.Date(time)) %>%
group_by(item_id) %>%
pad() %>% # from padr
fill(shop_id) %>% # from tidyr
fill_by_value(value) # from padr
数据:强>
# A tibble: 7 x 4
# Groups: item_id [2]
shop_id item_id time value
<int> <int> <date> <dbl>
1 150 1 2015-07-10 3
2 150 1 2015-07-11 5
3 150 1 2015-07-12 0
4 150 1 2015-07-13 2
5 150 2 2015-07-10 15
6 150 2 2015-07-11 0
7 150 2 2015-07-12 12