使用list()在函数内部提取data.table

时间:2014-08-20 20:28:02

标签: r data.table

我必须承认data.table j语法让我感到困惑。

我正在尝试使用list()提取data.table的子集作为data.table对象,如Section 1.4 of the data.table FAQ中所述,但我无法将此行为转移到require(data.table) ## Setup some test data set.seed(1) test.data <- data.table( X = rnorm(10), Y = rnorm(10), Z = rnorm(10) ) setkey(test.data, X) ## Notice that I can subset the data table easily with literal names test.data[, list(X,Y)] ## X Y ## 1: -0.8356286 -0.62124058 ## 2: -0.8204684 -0.04493361 ## 3: -0.6264538 1.51178117 ## 4: -0.3053884 0.59390132 ## 5: 0.1836433 0.38984324 ## 6: 0.3295078 1.12493092 ## 7: 0.4874291 -0.01619026 ## 8: 0.5757814 0.82122120 ## 9: 0.7383247 0.94383621 ## 10: 1.5952808 -2.21469989 在函数内部工作。

一个例子:

data.table

我甚至可以编写一个函数,当将列的名称作为字符向量传递时,它会将get.a.vector <- function( my.dt, my.column ) { ## Step 1: Convert my.column to an expression column.exp <- parse(text=my.column) ## Step 2: Return the vector return( my.dt[, eval(column.exp)] ) } get.a.vector( test.data, 'X') ## [1] -0.8356286 -0.8204684 -0.6264538 -0.3053884 0.1836433 0.3295078 ## [7] 0.4874291 0.5757814 0.7383247 1.5952808 的列作为向量返回:

list()

但我不能为browser()提出类似的伎俩。内联注释是交互式get.a.dt <- function( my.dt, my.column ) { ## Step 1: Convert my.column to an expression column.exp <- parse(text=my.column) ## Step 2: Enter the browser to play around browser() ## Step 3: Verity that a literal X works: my.dt[, list(X)] ## << not shown >> ## Step 4: Attempt to evaluate the parsed experssion my.dt[, list( eval(column.exp)] ## Error in `rownames<-`(`*tmp*`, value = paste(format(rn, right = TRUE), (from data.table.example.R@1032mCJ#7) : ## length of 'dimnames' [1] not equal to array extent return( my.dt[, list(eval(column.exp))] ) } get.a.dt( test.data, "X" ) 会话的输出。

set.seed(2)
test.data[, X.1 := rnorm(10)]
which.column <- 'X'
new.column   <- paste(which.column, '.1', sep="")

get.a.dt( test.data, new.column ) 

我错过了什么?

更新:

由于我为什么要这样做而感到困惑,我想澄清一下。我的用例是当我生成名称时需要访问data.table列。像这样:

{{1}}

希望这会有所帮助。

2 个答案:

答案 0 :(得分:5)

听起来你只是想要:

dt = data.table(a = 1:5, b = 2:6, c = 3:7)

var = "a"
dt[, var, with = FALSE]
#   a
#1: 1
#2: 2
#3: 3
#4: 4
#5: 5

但只是为了好玩,这里是一个通用的检索功能,您可以提供变量名称或变量:

retrieve = function(dt, ...) {
  vars = as.character(substitute(list(...))[-1])
  dt[, vars, with = FALSE]
}

retrieve(dt, a)
#   a
#1: 1
#2: 2
#3: 3
#4: 4
#5: 5

retrieve(dt, b, "c")
#   b c
#1: 2 3
#2: 3 4
#3: 4 5
#4: 5 6
#5: 6 7

答案 1 :(得分:0)

eval转到parent.frame()环境。如果您真的想使用此方法获取列(为什么?????),请使用get

get.a.dt <- function( my.dt, my.column ) {
    return( my.dt[, list(get(my.column))] )
}

get.a.dt( test.data, "X" )