R - 替换数据表中的缺失值

时间:2014-07-17 00:27:56

标签: r data.table

我有一个像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)

无法找到一种有效的方法。

2 个答案:

答案 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

然后使用yx的二进制子集替换缺少的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