Dynamic column names in data.table

前端 未结 3 1148
天涯浪人
天涯浪人 2020-11-28 06:19

I am trying to add columns to my data.table, where the names are dynamic. I addition I need to use the by argument when adding these columns. For

相关标签:
3条回答
  • 2020-11-28 06:46

    From data.table 1.9.4, you can just do this:

    ## A parenthesized symbol, `(cn)`, gets evaluated to "blah" before `:=` is carried out
    test_dtb[, (cn) := mean(a), by = id]
    head(test_dtb, 4)
    #     a  b id blah
    # 1: 41 19  1 54.2
    # 2:  4 99  2 50.0
    # 3: 49 85  3 46.7
    # 4: 61  4  4 57.1
    

    See Details in ?:=:

    DT[i, (colvector) := val]

    [...] NOW PREFERRED [...] syntax. The parens are enough to stop the LHS being a symbol; same as c(colvector)


    Original answer:

    You were on exactly the right track: constructing an expression to be evaluated within the call to [.data.table is the data.table way to do this sort of thing. Going just a bit further, why not construct an expression that evaluates to the entire j argument (rather than just its left hand side)?

    Something like this should do the trick:

    ## Your code so far
    library(data.table)
    test_dtb <- data.table(a=sample(1:100, 100),b=sample(1:100, 100),id=rep(1:10,10))
    cn <- "blah"
    
    ## One solution
    expr <- parse(text = paste0(cn, ":=mean(a)"))
    test_dtb[,eval(expr), by=id]
    
    ## Checking the result
    head(test_dtb, 4)
    #     a  b id blah
    # 1: 30 26  1 38.4
    # 2: 83 82  2 47.4
    # 3: 47 66  3 39.5
    # 4: 87 23  4 65.2
    
    0 讨论(0)
  • 2020-11-28 06:54

    I believe setnames(DT, c(col.names)) yields the most readable code

    0 讨论(0)
  • 2020-11-28 07:00

    Expression can be constructed with bquote.

    cn <- "blah"
    expr <- bquote(.(as.name(cn)):=mean(a))
    test_dtb[,eval(expr), by=id]
    
    0 讨论(0)
提交回复
热议问题