Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining multiple lists of variable names in data.table?

Tags:

r

data.table

I'm trying to pass two separate lists of variable names into a data.table (v1.9.4). It returns the correct columns, but it strips the variable names. This works as expected:

dt <- data.table(a=1:3, b=4:6, c=7:9, d=10:12)
dt
   a b c  d
1: 1 4 7 10
2: 2 5 8 11
3: 3 6 9 12

It also works fine to pass a single list of names:

dt[,list(a,b)]
   a b
1: 1 4
2: 2 5
3: 3 6

But when I need to pass multiple lists, it returns the correct columns but strips the variable names:

dt[,c(list(a,b), list(c,d))]
   V1 V2 V3 V4
1:  1  4  7 10
2:  2  5  8 11
3:  3  6  9 12

Why two lists? I'm using multiple quote()'d lists of variables. I've read FAQ question 1.6, and I know that one workaround is to use a character vector using with=FALSE. But my real use case involves passing a mix of names and expressions to a function, e.g.,

varnames <- quote(list(a,b))
expr <- quote(list(a*b, c+d))
function(dt, varnames, expr) {
  dt[,c(varnames, expr)]
}

And I'd like the "varnames" columns to have their proper names (and they do if you just pass a single list like

dt[,list(a,b,a*b,c+d)]
   a b V3 V4
1: 1 4  4 17
2: 2 5 10 19
3: 3 6 18 21

How can I combine multiple lists in a data.table such that it still returns the proper column names? (I'm not completely sure if this is a data.table issue or if I'm just doing something silly in the way I'm trying to combine lists in R, but c() seems to do what I want.)

like image 794
cauchy Avatar asked May 05 '15 19:05

cauchy


People also ask

How to combine data tables?

For database-like merging/joining of tables, use the merge function. See the user guide for a full description of the various facilities to combine data tables. How to reshape the layout of tables?

How to combine three lists of data into one list?

We need to combine these three lists into one list that contains all the data for all three years. The following are the steps for combining the lists. Make a copy of the ‘2012' sheet and rename it to ‘Combined Data'. In cell E1 add the text “Year”. This new column will represent the year for each list of data.

How to merge two DataTable objects with similar schemas?

The Mergemethod is used to merge two DataTableobjects that have largely similar schemas. A merge is typically used on a client application to incorporate the latest changes from a data source into an existing DataTable. This allows the client application to have a refreshed DataTablewith the latest data from the data source.

How to modify data from one table to another table?

Create a DataTable (table1) and fill the table with data. // 2. Create a copy of table1, and modify its data (modifiedTable). // 3. Modify data in table1. // 4. Make a copy of table1 (table1Copy). // 5.


2 Answers

Another option is to construct the full call ahead of time:

varnames[4:5] <- expr[2:3]  # this results in `list(a, b, a * b, c + d)`
dt[, eval(varnames)]

produces:

   a b V3 V4
1: 1 4  4 17
2: 2 5 10 19
3: 3 6 18 21

More generically, suppose you have a list of quoted lists of expressions:

exprlist <- list(quote(list(a, b)), quote(list(c, c %% a)), quote(list(a + b)))
expr <-  as.call(Reduce(function(x, y) c(as.list(x), as.list(y)[-1]), exprlist))  # @eddi
dt[, eval(expr)]
like image 166
BrodieG Avatar answered Oct 30 '22 07:10

BrodieG


Here's a possible workaround using .SD

varnames <- quote(list(a,b))
expr <- quote(list(a*b, c+d))

myFunc <- function(dt, varnames, expr) {
  dt[, c(.SD[, eval(varnames)], eval(expr))]
}

myFunc(dt, varnames, expr)

#    a b V1 V2
# 1: 1 4  4 17
# 2: 2 5 10 19
# 3: 3 6 18 21
like image 30
David Arenburg Avatar answered Oct 30 '22 09:10

David Arenburg