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.)
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?
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.
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.
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.
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)]
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With