1
votes

I have the following data.table:

dt <- data.table(reg=letters[c(2:4)],list_reg_size=c(2:4))
   reg list_reg_size
1:   b             2
2:   c             3
3:   d             4

I wrote the following function that nests a char vector inside a new column list_dt:

create_list <- function(dt){
  dt[,list_dt:=list(letters[1:list_reg_size])]
}

that provides the correct output for a single element, appending a column containing a nested list to the input :

(subset <- dt[1])
   reg list_reg_size
1:   b             2

create_list(subset)
subset
   reg list_reg_size list_dt
1:   b             2     a,b

Please note that the size of the list varies with list_reg_size of each row, such as the desired result for dt would be:

create_list(dt))
dt
reg list_reg_size list_dt
1:   b             2     a,b
2:   c             3     a,b,c
3:   d             4     a,b,c,d

However, when I run the code above I get:

   reg list_reg_size list_dt
1:   b             2     a,b
2:   c             3     a,b
3:   d             4     a,b

I tried lapply(dt, create_list) that throws an error:

Error in `:=`(list_dt, list(letters[1:list_reg_size])) : 
Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":="). 

How do I vectorize this function to get the desired output? Thank you.

2

2 Answers

3
votes

This is how to solve your problem in base R. Not data table, I know, but it might be useful:

df <- data.frame(reg=letters[c(2:4)],list_reg_size=c(2:4),
                 stringsAsFactors = FALSE)

create_list <- function(list_reg_size){
 list(letters[1:list_reg_size])
}

UPDATE

As @chinsoon12 pointed out, one can use

setDT(df)[,list_dt:=sapply(list_reg_size, function(n) list(letters[seq_len(n)]))] 

for data.table.

2
votes

In data.table, you can also do:

dt[, list(list_dt = paste(letters[1:list_reg_size], collapse = ",")), 
          by = c("reg", "list_reg_size")]