Do i need to convert the individual elements of j to a list if the overall result of j is a list?

Background

The main property data.tableis that

"As long as it jreturns a list, each list item becomes a column in the resulting data table."

This is shown, for example. in the example from ?data.table:

library(data.table)
DT[, c(.N, lapply(.SD, sum)), by=x]

Here the integer is .Nequal cto which is included in the list obtained as a result lapply, and the total result is a list, i.e. .Nimplicitly coerced to a list item (according to the coercion hierarchy described in ?c)

What caught my attention was the example used both in ?data.tableand in .SD, where, unlike the above, the non-list part is jexplicitly converted to a list:

DT[, c(.(y=max(y)), lapply(.SD, min)), by=rleid(v), .SDcols=v:b]

It does not immediately seem to me why the single number obtained in y=max(y)this example is converted to list ( .()) when it is converted to a list item in any case, after concatenation with list ( lapply(.SD.,).


Explicit is listnot needed?

Here is a small example, where max(y)and sumall the variables are calculated using the variable group. structure and the result of calculations really coincide, both when explicitly converting the result of "non-list" to ja list, and in the absence of this:

dt <- data.table(grp = rep(c("a", "b"), 2:3), x = 1:5, y = 2:6)

# - structure of j
dt[ , str(c(.(ymax = max(y)), lapply(.SD, sum))), by = grp]
dt[ , str(c(ymax = max(y), lapply(.SD, sum))), by = grp]

# - result of j
dt[ , c(.(ymax = max(y)), lapply(.SD, sum)), by = grp]
dt[ , c(ymax = max(y), lapply(.SD, sum)), by = grp]

# ...both give the same result:

, j . ? , .N .


list, .N!

"non-list" j .N, j , .

str j , .N, j:

dt[ , str(c(.(n = .N), lapply(.SD, sum))), by = grp]
dt[ , str(c(n = .N, lapply(.SD, sum))), by = grp]

# List of 3
#  $ n: int 2
#  $ x: int 3
#  $ y: int 5
# List of 3
#  $ n: int 3
#  $ x: int 12
#  $ y: int 15

~~ > , str ".N" , j, "n".

, .N "list ed" j, .N "N" (. ?.N) :

dt[ , c(.(n = .N), lapply(.SD, sum)), by = grp]
#    grp n  x  y
# 1:   a 2  3  5
# 2:   b 3 12 15

dt[ , c(n = .N, lapply(.SD, sum)), by = grp]
#    grp N  x  y
# 1:   a 2  3  5
# 2:   b 3 12 15

, .(), , , j / .

.N ( ) , list, , ? , ?

+3
1

-, @Frank, , .N . ( ), , list j.

.N , . FWIW, , ( ).

1: .N

1a: .N autonamed 'N', (1) .N , (2) .N by, (3) .N lapply by.

1b: .N autonamed 'V1', 'N' (1) .N lapply, (2) list(.N) lapply

# 1a: .N is autonamed 'N'

# .N only
dt[ , .(.N)]
#    N
# 1: 5

# .N + by
dt[ , .(.N), by = grp]
#   grp N
# 1:  a 2
# 2:  b 3

# .N + lapply + by 
dt[ , c(.N, lapply(.SD, max)), by = grp]
#    grp N x y
# 1:   a 2 2 3 
# 2:   b 3 5 6


# 1b: .N is autonamed V1, instead of N

# .N + lapply
dt[ , c(.N, lapply(.SD, max))]
#    V1 grp x y
# 1:  5   b 5 6

# list(.N) + lapply
d[ , c(.(.N), lapply(.SD, max))]
#    V1 grp x  y
# 1:  5   2 5 10

2: .N

2: list(.N) .N lapply

2b: list(.N) .N lapply by.

# 2a: list(.N) not needed

# .N + lapply
dt[ , c(n = .N, lapply(.SD, max))]
#    n grp x y
# 1: 5   b 5 6


# 2b: list(.N) needed

# .N + lapply + by
dt[ , c(.(n = .N), lapply(.SD, max)), by = grp]
#    grp n x y
# 1:   a 2 2 3
# 2:   b 3 5 6

+3

All Articles