How does data.table get the column name from j?

For example:

dt <- data.table()
x=1:5
> dt[,list(2,3,x)]
   V1 V2 x
1:  2  3 1
2:  2  3 2
3:  2  3 3
4:  2  3 4
5:  2  3 5

The resulting data table has a column x

For some reason, I would like to create a function to simplify the construction of data.table.

tt <- function(a, b, ...){
    list(a=sum(a), b=sum(b), ...)
}

> dt[,tt(1:2,1:3,x)]
   a b V3
1: 3 6  1
2: 3 6  2
3: 3 6  3
4: 3 6  4
5: 3 6  5

Therefore, whenever I call list, I use instead tt, so it automatically inserts predefined columns for me. However, now it does not recognize the shortcut name for x.

How to improve ttfor an automatic column name like listin data.table if it is not too complicated?

purpose

dt[,tt(1:2,1:3,x)]

Returns

   a b  x
1: 3 6  1
2: 3 6  2
3: 3 6  3
4: 3 6  4
5: 3 6  5

Decision

tt <- function(a, b, ...){
    dots <- list(...)
    inferred <- sapply(substitute(list(...)), function(x) deparse(x)[1])[-1]
    if(is.null(names(inferred))){
        names(dots) <- inferred
    } else {
        names(dots)[names(inferred) == ""] <- inferred[names(inferred) == ""]
    }
    c(a=sum(a), b=sum(b), dots)
}

dt <- data.table(c=1:5)
x=1:5

> dt[,tt(1:2,1:3,x,c+1)]
   a b x c + 1
1: 3 6 1     2
2: 3 6 2     3
3: 3 6 3     4
4: 3 6 4     5
5: 3 6 5     6
> dt[,tt(1:2,1:3,x, z=c+1)]
   a b x z
1: 3 6 1 2
2: 3 6 2 3
3: 3 6 3 4
4: 3 6 4 5
5: 3 6 5 6

Update

I recently discovered that there was some error on page 46 of S Programming from Venables and Ripley. I made some changes and posted them here. Hope this would be helpful for some people.

# Get the best names vector for arguments like what data.frame does.
# Modified from page 46 of S Programming from Venables & Ripley.
# http://stackoverflow.com/questions/20545476/how-does-data-table-get-the-column-name-from-j
name.args <- function(...){
    # Get a list of arguments.
    dots <- as.list(substitute(list(...)))[-1]
    # Get names of the members if they have, otherwise "".
    # If a list have no named members, it returns NULL.
    nm <- names(dots)
    # If all arguments are named, return the names directly.
    # Otherwise it would cause a problem when do nm[logic(0)] <- list().
    if (!is.null(nm) && all(nm != ""))
        return(nm)
    # Handle empty argument list case.
    if (length(dots) == 0)
        return(character(0))
    # Get positions of arguments without names.
    fixup <- 
        if (is.null(nm))
            seq(along=dots)
        else
            nm == ""
    dep <- sapply(dots[fixup], function(x) deparse(x)[1])
    if (is.null(nm))
        dep
    else {
        nm[fixup] <- dep
        nm
    }
}

# Example
# x <- 1:2
# name.args(x, y=3, 5:6)
# name.args(x=x, y=3)
# name.args()
+4
1

, :

dt[,tt(1:2,1:3,x=x)]   ## Note that this uses `x=x` rather than just `x`
#    a b x
# 1: 3 6 1
# 2: 3 6 2
# 3: 3 6 3
# 4: 3 6 4
# 5: 3 6 5

, - ;)

tt <- function(a, b, ...){
    dots <- list(...)
    names(dots) <- as.character(substitute(list(...))[-1])
    c(a=sum(a), b=sum(b), dots)
}
dt[,tt(1:2,1:3,x)]
#    a b x
# 1: 3 6 1
# 2: 3 6 2
# 3: 3 6 3
# 4: 3 6 4
# 5: 3 6 5
+7

All Articles