我有一个像dt这样的数据表。它基本上是完整的,但有一些缺失值,我试图以合理的方式填写。
set.seed(2015)
require(data.table)
dt<-data.table(id=1:10, x=sample(letters[1:3],10,replace=TRUE), y=sample(letters[4:6],10,replace=TRUE), key="id")
dt[sample(10,3), y:=""]
dt
id x y
1: 1 a f
2: 2 c
3: 3 a d
4: 4 a
5: 5 a f
6: 6 b f
7: 7 b
8: 8 a d
9: 9 b f
10: 10 b e
对于每个缺失的y,我想将y值设置为等于x中其类的最频繁(非空白)y值。在平局的情况下,选择并列赢家的随机y。如果没有获胜者,请留空。在这个例子中,我的数据表应该转换为
id x y
1: 1 a f
2: 2 c
3: 3 a d
4: 4 a d
5: 5 a f
6: 6 b f
7: 7 b f
8: 8 a d
9: 9 b f
10: 10 b e
或
id x y
1: 1 a f
2: 2 c
3: 3 a d
4: 4 a f
5: 5 a f
6: 6 b f
7: 7 b f
8: 8 a d
9: 9 b f
10: 10 b e
(第4行中的y值可以变为d或f)
无法找到一种有效的方法。
答案 0 :(得分:4)
我首先会获得相应的条目,将y
替换为x
中的每个值,如下所示:
idt = dt[, .N, by="x,y"][, list(y=sample(y[N %in% max(N)], 1L)), by=x]
# x y
# 1: a d
# 2: c
# 3: b f
然后使用y
上x
的二进制子集替换缺少的idt
引用,如下所示:
setkey(idt, x)
dt[y == "", y := idt[x]$y]
# id x y
# 1: 1 a f
# 2: 2 c
# 3: 3 a d
# 4: 4 a d
# 5: 5 a f
# 6: 6 b f
# 7: 7 b f
# 8: 8 a d
# 9: 9 b f
# 10: 10 b e
答案 1 :(得分:2)
不确定这是否最快,但你可以做到:
dt[, z := ifelse(y!="", y, if(length(el <- sort(table(y[y!=""]), decreasing = TRUE)) > 0 ) {names(el)[1]} else {""}),by=x]
然后你会得到
> dt
id x y z
1: 1 a f f
2: 2 c
3: 3 a d d
4: 4 a d
5: 5 a f f
6: 6 b f f
7: 7 b f
8: 8 a d d
9: 9 b f f
10: 10 b e e