我有一个像这样的data.table(只有更多的列,明显更大的^^)
> DT = data.table(a=c(1,1,2,2),b=c(1,1,1,2),c=c(2,2,2,2),num=c(6,5,4,3))
> DT
a b c num
1: 1 1 2 6
2: 1 1 2 5
3: 2 1 2 4
4: 2 2 2 3
我想编写一个函数getContent()
,它按降序返回给定indecies(a,b,c)的所有num-values。例如。 getContent(c(1,1,2))
wourld返回“6 5”。
但是,给定的下限可以是NA,我想将它们视为通配符,因此getContent(c(NA,1,2))
将返回“6 5 4”而getContent(c(2,NA,2))
将返回“4 3”
我发现了一种在不使用if / else逻辑的情况下返回所有num-values的方法:
getContent <- function(Indecies){
setkeyv(DT,letters[1:3][!is.na(Indecies)])
DT[as.list(Indecies[!is.na(Indecies)]),num]
}
但是有更好(即更快)的方式吗?特别是没有设置DT的键?我的意思是getContent(c(2,NA,2))
可以实现为DT[a==2 & c==2,num]
如何按降序返回列表而不将其作为后处理步骤排序? (我想使用setorderv(DT,c(letters[1:3][!is.na(Indecies)],-num))
但是这不起作用,尽管错误说'标记为已排序'就足够了)
所以这样的事情会很好:
getContent <- function(Indecies){
DT[as.list(Indecies[!is.na(Indecies)]),num,
by=.(letters[1:3][!is.na(Indecies)],-num)]
}
非常感谢任何帮助或链接! : - )
答案 0 :(得分:3)
直截了当的解决方案对你来说不够好吗?
setorder(DT, -num)
getContent = function(idx) {
if (all(is.na(idx))) return (DT[, num])
cols = names(DT)[which(!is.na(idx))]
vals = idx[!is.na(idx)]
DT[eval(parse(text = paste(cols, vals, sep = " == ", collapse = " & "))), num]
}
getContent(c(1, NA, 2))
#[1] 6 5