1

I have this data.table:

DT <- data.table(num=c(1,4,6,7,8,12,13, 15), let=rep(c("A","B"), each=4))

Displayed like this:

   num let
1:   1   A
2:   4   A
3:   6   A
4:   7   A
5:   8   B
6:  12   B
7:  13   B
8:  15   B

And I define this function:

f<-function(x){return(c(x+1,x+2))}

I want to get this:

   let V1 V2
1:   A  2  3
2:   A  5  6
3:   A  7  8
4:   A  8  9
5:   B  9 10
6:   B 13 14
7:   B 14 15
8:   B 16 17

I run this code:

DT[,list(f(num)),by=let]

and

DT[,f(num),by=let]

But I get this:

    let V1
 1:   A  2
 2:   A  5
 3:   A  7
 4:   A  8
 5:   A  3
 6:   A  6
 7:   A  8
 8:   A  9
 9:   B  9
10:   B 13
11:   B 14
12:   B 16
13:   B 10
14:   B 14
15:   B 15
16:   B 17

I would add that I do not want to modify the function f at all.

1 Answer 1

8
DT[, as.data.table(matrix(f(num), ncol=2)), by=let]
#   let V1 V2
#1:   A  2  3
#2:   A  5  6
#3:   A  7  8
#4:   A  8  9
#5:   B  9 10
#6:   B 13 14
#7:   B 14 15
#8:   B 16 17

Of course it would be preferable and more efficient to simply change the function, since its design is the problem and not data.table. Your function will always return an atomic vector, regardless of if it is used inside data.table.

f <- function(x) list(x+1, x+2)
DT[, f(num), by=let]
Sign up to request clarification or add additional context in comments.

2 Comments

Oh thanks, modifying the function is the best way! I dunno if it possible to change the name of V1 and V2 by the way.
f <- function(x) list(a=x+1, b=x+2) or if you prefer not modifying the function DT[, setNames(f(num), c("a", "b")), by=let].

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.