data.table CJ,字符串作为输入

时间:2018-02-27 16:25:50

标签: r data.table

如何以字符串作为输入运行CJ命令?以下MNWE说明了所需:

library(data.table)
# This is the desired output (when needed.cols==2)
dt.wanted <- CJ(X.1=c(1L, 2L), X.2=c(1L, 2L))
# Here is an example with needed.cols as variable
needed.cols <- 2L
use.text <- paste0("X.", 1L:needed.cols, "=c(1L, 2L)", collapse=", ")
# Here are some failing attempts
dt.fail <- CJ(use.text)
dt.fail <- CJ(eval(use.text))
dt.fail <- CJ(get(use.text))

所以我想制作可编写脚本的use.text(因为它不同,不仅仅是need.cols)。

2 个答案:

答案 0 :(得分:1)

get - 函数是将字符值提升为真实R名称值的标准方法。

这就是你想要的:

col.wanted =2
dt.wanted[ , get(paste0("X.", col.wanted) )]
#[1] 1 2 1 2

根据对更复杂表达式的评估获取多个列可能需要更多巴洛克式的努力:

> use.text <- paste0("list(", paste0("X.", 1L:needed.cols, collapse=", "),")")
> use.text
[1] "list(X.1, X.2)"
> dt.wanted[ , eval(use.text)]
[1] "list(X.1, X.2)"
> dt.wanted[ , parse(text=use.text)]
expression(list(X.1, X.2))

> dt.wanted[ , eval(parse(text=use.text))]
   X.1 X.2
1:   1   1
2:   1   2
3:   2   1
4:   2   2

答案 1 :(得分:1)

IIUC,您正在寻找一个函数将参数列表传递给函数的...。您可以使用do.call执行此操作,如下所示:

do.call(CJ, eval(parse(text=paste0("list(",use.text,")"))))

希望这就是你要找的......