动态构建查找多列的调用 [英] Dynamically build call for lookup multiple columns

查看:26
本文介绍了动态构建查找多列的调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何动态查找多个字段并通过引用添加 使用字符向量变量作为参数.在下面的情况下,我想查找两列并去掉其中的 i. 前缀.当然他们可以覆盖已经存在的同名列.

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 rid of i. prefix in them. Of course they can override already existing columns with the same name.

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
j.lkp <- call(":=", select, lapply(paste0("i.",select), as.symbol))
j.lkp
# `:=`(c("value", "meta"), list(i.value, i.meta))
ID[JN, eval(j.lkp)]
# Error in eval(expr, envir, enclos) : could not find function "i.value"
ID[JN, `:=`(c("value", "meta"), list(i.value, i.meta))]
#    id meta value
# 1:  1    1     x
# 2:  2    1     v
# 3:  3    1     f

我知道 类似问题,但这个问题在加入期间要求矢量化参数并直接构建对 j 的调用.
我知道我可以使用 .SDcols 来做到这一点,但是我无法通过参考来执行此操作

I'm aware of similar question but this one asks for vectorized argument during join and directly building call for j.
edit: I'm aware I can do it using .SDcols but then I cannot perform this by reference

推荐答案

在最近的开发版本中,它变得更加容易

In recent development version it has been made much easier

ID[JN, (select) := .list_of_fields,
   env=list(.list_of_fields=as.list(paste0('i.', select)))]

1.14.1 之前的旧解决方案

除了 mgeteval-parse 之外,仍然可以构建查找调用.虽然 mget 是最用户友好的,但它既灵活又实际上对应于构建 j 表达式.
解决方案包含在 batch.lookup 辅助函数中,用于查找列名的字符向量.

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

公平地说,这个答案实际上解决了我作为 OP 描述的呼叫构造问题.

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

这篇关于动态构建查找多列的调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆