0

This is related to this question from Henrik Assign multiple columns using := in data.table, by group

But what if I want to create a new data.table with given column names instead of assigning new columns to an existing one?

f <- function(x){list(head(x,2),tail(x,2))}
dt <- data.table(group=sample(c('a','b'),10,replace = TRUE),val=1:10)

> dt
    group val
 1:     b   1
 2:     b   2
 3:     a   3
 4:     b   4
 5:     a   5
 6:     b   6
 7:     a   7
 8:     a   8
 9:     b   9
10:     b  10

I want to get a new data.table with predefined column names by calling the function f:

dt[,c('head','tail')=f(val),by=group]

I wish to get this:

   group head tail
1:     a    1    8
2:     a    3   10
3:     b    2    6
4:     b    5    9

But it gives me an error. What I can do is create the table then change the column names, but that seems cumbersome:

> dt2 <- dt[,f(val),by=group]

> dt2
   group V1 V2
1:     a  1  8
2:     a  3 10
3:     b  2  6
4:     b  5  9

> colnames(dt2)[-1] <- c('head','tail')

> dt2
   group head tail
1:     a    1    8
2:     a    3   10
3:     b    2    6
4:     b    5    9

Is it something I can do with one call?

5
  • 1
    Why don't you just define f with the names in it? f <- function(x){list(head = head(x,2), tail = tail(x,2))}? Or, I guess dt[, setNames(f(val), c("head", "tail")), group] should work. Commented Aug 9, 2017 at 17:21
  • @A5C1D2H2I1M1N2O1R2T1 Downside to the second way is that data.table complains (albeit only quietly, when verbose = TRUE). I guess the real issue is that when using data.table programmatically (at least in ways as general as the OP wants), it's best to construct expressions or full [.data.table calls to evaluate... Commented Aug 9, 2017 at 17:33
  • @A5C1D2H2I1M1N2O1R2T1 As Frank said, the names in the data table will be determined programmatically so I cannot hard-code it in the function. But your second way does work. Thanks. Commented Aug 9, 2017 at 19:32
  • @Frank by 'it's best to construct expressions', do you mean to have an inline function instead of calling an existing one? Commented Aug 9, 2017 at 19:33
  • I mean something like github.com/franknarf1/r-tutorial/issues/11 It gets pretty messy, so I rarely build tables + functions where I'll need to determine input or output column names dynamically. Here's another example: stackoverflow.com/questions/37007282/… and more generally google.com/… Commented Aug 9, 2017 at 19:42

1 Answer 1

0

From running your code as-is, this is the error I get:

dt[,c('head','tail')=f(val),by=group]
# Error: unexpected '=' in "dt2[,c('head','tail')="

The problem is using = instead of := for assignment.

On to your problem of wanting a new data.table:

dt2 <- dt[, setNames(f(val), c('head', 'tail')), by = group]
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this works. Although @A5C1D2H2I1M1N2O1R2T1 gave this solution earlier in the comment. Still accepting your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.