我有一个data.table,缺少值,其中某些行只包含NA' s。 data.table
实际上是较大data.table
列的子集,因此我希望避免丢弃所有NA行。我想找到一种优雅的方法来找到每行中具有最小元素的列的索引,并将结果数组作为新列添加到data.table
。对于所有NA行,我想要NA结果。这是一种不太优雅的方式:
> dt <- data.table(x=c(1,NA,3),y=c(2,NA,NA),z=c(3,NA,1))
> dt
x y z
1: 1 2 3
2: NA NA NA
3: 3 NA 1
> w <- apply(dt,1,which.min)
> w
[[1]]
x
1
[[2]]
integer(0)
[[3]]
z
3
> v <- unlist(lapply(w,function(z) ifelse(length(z)==0, NA, z[1])))
> v
[1] 1 NA 3
> dt$idx <- v
> dt
x y z idx
1: 1 2 3 1
2: NA NA NA NA
3: 3 NA 1 3
正如您所看到的,不优雅的主要原因是apply
创建了一个列表而不是一个数组。发生这种情况是因为每行的结果长度不同。此外,我正在调用base-R函数which.min
,apply
,unlist
和lapply
。 是否有紧凑的data.table
方式来获得所需的结果?
答案 0 :(得分:3)
使用.SD
d[, idx := apply(.SD, 1, which.min), .SDcols = c('x', 'y', 'z')]
但是所有NA行都是空白的;实际上,因为第二行都是NA,which.min将返回integer(0)
,因此apply
的结果长度不等,d $ idx是一个列表(其中第二行是零 - 长度矢量);
> d
x y z idx
1: 1 2 3 1
2: NA NA NA
3: 3 NA 1 3
> d$idx
[[1]]
x
1
[[2]]
integer(0)
[[3]]
z
3
所以要处理零长度向量并在这些情况下设置返回NA;
d[, idx := apply(.SD, 1, function(x) which.min(x)[1] ), .SDcols = c('x', 'y', 'z')]
> d$idx
[1] 1 NA 3