Using list() to extract a data.table inside of a function

Posted by Nathan VanHoudnos on Stack Overflow See other posts from Stack Overflow or by Nathan VanHoudnos
Published on 2014-08-20T20:28:02Z Indexed on 2014/08/20 22:20 UTC
Read the original article Hit count: 168

Filed under:
|

I must admit that the data.table J syntax confuses me.

I am attempting to use list() to extract a subset of a data.table as a data.table object as described in Section 1.4 of the data.table FAQ, but I can't get this behavior to work inside of a function.

An example:

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

I can even write a function that will return a column of the data.table as a vector when passed the name of a column as a character vector:

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

But I cannot pull a similar trick for list(). The inline comments are the output from the interactive browser() session.

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" )

What am I missing?

Update:

Due to some confusion as to why I would want to do this I wanted to clarify. My use case is when I need to access a data.table column when when I generate the name. Something like this:

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 ) 

Hopefully that helps.

© Stack Overflow or respective owner

Related posts about r

    Related posts about data.table