Dynamically build call for lookup multiple columns

前端 未结 3 1553
南旧
南旧 2020-11-27 20:19

How can I dynamically lookup multiple fields and add by reference using character vector variable as argument. In below case I want to lookup two columns and get ri

相关标签:
3条回答
  • 2020-11-27 21:06

    Here's the crude way:

    myj <- parse(text=paste0("`:=`(",paste0(select,"=i.",select,collapse=","),")"))
    ID[JN,eval(myj)]
    #    id meta value
    # 1:  1    1     x
    # 2:  2    1     v
    # 3:  3    1     f
    
    0 讨论(0)
  • 2020-11-27 21:12

    Instead of mget or eval-parse there is still possibility to build the lookup call. While the mget is the most user friendly, this one is both flexible and actually corresponds to building the j expression.
    Solution wrapped into batch.lookup helper function taking character vector of column names to lookup.

    library(data.table)
    set.seed(1)
    ID <- data.table(id = 1:3, meta = rep(1,3), key = "id")
    JN <- data.table(idd = sample(ID$id, 3, FALSE), value = sample(letters, 3, FALSE), meta = rep(1,3), key = "idd")
    select <- c("value","meta") # my fields to lookup
    
    batch.lookup = function(x) {
        as.call(list(
            as.name(":="),
            x,
            as.call(c(
                list(as.name("list")),
                sapply(x, function(x) as.name(paste0("i.",x)), simplify=FALSE)
            ))
        ))
    }
    batch.lookup(select)
    #`:=`(c("value", "meta"), list(value = i.value, meta = i.meta))
    ID[JN, eval(batch.lookup(select))][]
    #   id meta value
    #1:  1    1     x
    #2:  2    1     v
    #3:  3    1     f
    

    To be fair this answer actually address call construction issue described by me as OP.

    0 讨论(0)
  • 2020-11-27 21:17

    This seems to be the most straightforward way to me:

    ID[JN, (select) := mget(paste0('i.', select))]
    
    0 讨论(0)
提交回复
热议问题