用 "wildcards" 子集 data.table 中的行
subsetting rows in data.table with "wildcards"
我有一个像这样的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()
,该函数 return 按降序排列给定索引 (a,b,c) 的所有数值。例如。 getContent(c(1,1,2))
世界 return "6 5".
但是给定的索引可以是 NA,我想把它们当作通配符,所以 getContent(c(NA,1,2))
会 return "6 5 4" 而 getContent(c(2,NA,2))
会 return “4 3”
我找到了一种方法 return 没有 if/else 逻辑的所有数值:
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]
我如何 return 列表按降序排列而不将其排序为 post 处理步骤? (我想使用 setorderv(DT,c(letters[1:3][!is.na(Indecies)],-num))
但这不起作用,尽管错误说 'marked as sorted' 就足够了)
所以像这样的东西会很好:
getContent <- function(Indecies){
DT[as.list(Indecies[!is.na(Indecies)]),num,
by=.(letters[1:3][!is.na(Indecies)],-num)]
}
非常感谢任何帮助或链接! :-)
直截了当的解决方案对您来说不够好吗?
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
我有一个像这样的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()
,该函数 return 按降序排列给定索引 (a,b,c) 的所有数值。例如。 getContent(c(1,1,2))
世界 return "6 5".
但是给定的索引可以是 NA,我想把它们当作通配符,所以 getContent(c(NA,1,2))
会 return "6 5 4" 而 getContent(c(2,NA,2))
会 return “4 3”
我找到了一种方法 return 没有 if/else 逻辑的所有数值:
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]
我如何 return 列表按降序排列而不将其排序为 post 处理步骤? (我想使用 setorderv(DT,c(letters[1:3][!is.na(Indecies)],-num))
但这不起作用,尽管错误说 'marked as sorted' 就足够了)
所以像这样的东西会很好:
getContent <- function(Indecies){
DT[as.list(Indecies[!is.na(Indecies)]),num,
by=.(letters[1:3][!is.na(Indecies)],-num)]
}
非常感谢任何帮助或链接! :-)
直截了当的解决方案对您来说不够好吗?
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