我有以下data.table:
dt <- data.table(date=rep(c(2014,2013), each=4), price=c(3.14, 1.45, 3.4 ,5.1, 1, 2.3, 2.79, 3), brand=rep(c("Mercedes", "Audi"), each=4), num=c(3,6,7,8,3,5,9,12), seller=rep(c("gregory", "dan"), each=4))
导致:
date price brand num seller
1: 2013 1.00 Audi 3 dan
2: 2013 2.30 Audi 5 dan
3: 2013 2.79 Audi 9 dan
4: 2013 3.00 Audi 12 dan
5: 2014 3.14 Mercedes 3 gregory
6: 2014 1.45 Mercedes 6 gregory
7: 2014 3.40 Mercedes 7 gregory
8: 2014 5.10 Mercedes 8 gregory
我的目标是:
date num price brand seller
1: 2013 3 1.00 Audi dan
2: 2013 5 2.30 Audi dan
3: 2013 6 NA Audi dan
4: 2013 7 NA Audi dan
5: 2013 8 NA Audi dan
6: 2013 9 2.79 Audi dan
7: 2013 12 3.00 Audi dan
8: 2014 3 3.14 Mercedes gregory
9: 2014 5 NA Mercedes gregory
10: 2014 6 1.45 Mercedes gregory
11: 2014 7 3.40 Mercedes gregory
12: 2014 8 5.10 Mercedes gregory
13: 2014 9 NA Mercedes gregory
14: 2014 12 NA Mercedes gregory
我首先为每个日期添加缺失数字的行:
setkey(dt, date, num)
dtt<-dt[CJ(unique(date), unique(dt[,num]))]
实现第一步:
date num price brand seller
1: 2013 3 1.00 Audi dan
2: 2013 5 2.30 Audi dan
3: 2013 6 NA NA NA
4: 2013 7 NA NA NA
5: 2013 8 NA NA NA
6: 2013 9 2.79 Audi dan
7: 2013 12 3.00 Audi dan
8: 2014 3 3.14 Mercedes gregory
9: 2014 5 NA NA NA
10: 2014 6 1.45 Mercedes gregory
11: 2014 7 3.40 Mercedes gregory
12: 2014 8 5.10 Mercedes gregory
13: 2014 9 NA NA NA
14: 2014 12 NA NA NA
然后:
dtt[date==2013, c("brand","seller"):=list("Audi","dan")]
dtt[date==2014, c("brand","seller"):=list("Mercedes","gregory")]
给出想要的结果。
然而:
1 - 最后一段代码很糟糕。
2 - 我想制作一个通用函数(或连接),因为我有很多不同的日期和列来替换/保留我的真实数据中的NA。表。
看起来很简单,但我被困住了!
答案 0 :(得分:2)
怎么样:
require(data.table) ## 1.9.2
setkey(dt, num)
nums = unique(dt$num)
dt[, list(price=.SD[J(nums)]$price, brand=brand[1L],
num=nums, seller=seller[1L]), by=date]
# date price brand num seller
# 1: 2014 3.14 Mercedes 3 gregory
# 2: 2014 NA Mercedes 5 gregory
# 3: 2014 1.45 Mercedes 6 gregory
# 4: 2014 3.40 Mercedes 7 gregory
# 5: 2014 5.10 Mercedes 8 gregory
# 6: 2014 NA Mercedes 9 gregory
# 7: 2014 NA Mercedes 12 gregory
# 8: 2013 1.00 Audi 3 dan
# 9: 2013 2.30 Audi 5 dan
# 10: 2013 NA Audi 6 dan
# 11: 2013 NA Audi 7 dan
# 12: 2013 NA Audi 8 dan
# 13: 2013 2.79 Audi 9 dan
# 14: 2013 3.00 Audi 12 dan
或者:
dt[, c(.SD[J(nums), list(price=price)], brand=brand[1L],
seller=seller[1L]), by=date]
其中列的顺序不同。
在1.9.3
中,这将更有效(在语法和速度方面),因为我们不必加入并返回所有列:
## 1.9.3
dt[, list(price=.SD[J(nums), price], brand=brand[1L],
num=nums, seller=seller[1L]), by=date]
.SD[J(nums), price]
将导致向量,而不是先前版本中的data.table
,并且不会执行隐式(by-without-by),因此也会更快。
详细了解v1.9.3 here实施的新FR(第1点和第2点)下的内容。
HTH
答案 1 :(得分:2)
您可以使用roll
参数填充NA
的最近值。问题是,这也将填补price
,但这很容易解决:
setkey(dt, date, num)
dt[CJ(unique(date), unique(num)), roll = 'nearest'][!dt, price := NA][]
# date price brand num seller
# 1: 2013 1.00 Audi 3 dan
# 2: 2013 2.30 Audi 5 dan
# 3: 2013 NA Audi 6 dan
# 4: 2013 NA Audi 7 dan
# 5: 2013 NA Audi 8 dan
# 6: 2013 2.79 Audi 9 dan
# 7: 2013 3.00 Audi 12 dan
# 8: 2014 3.14 Mercedes 3 gregory
# 9: 2014 NA Mercedes 5 gregory
#10: 2014 1.45 Mercedes 6 gregory
#11: 2014 3.40 Mercedes 7 gregory
#12: 2014 5.10 Mercedes 8 gregory
#13: 2014 NA Mercedes 9 gregory
#14: 2014 NA Mercedes 12 gregory
我认为这应该比.SD[...]
解决方案快得多。