如何在R中的data.table中使用变量的列名完全通用

我正在寻找的是以下解决方法/工作流程的“最佳实践批准”替代方案。考虑到我有一堆相似数据的列,并想对这些列或它们的集合执行一系列相似的操作,其中这些操作的复杂度非常高,并且将列名的组传递给指定的每个操作在一个变量中。


我意识到这个问题听上去是人为的,但是我以惊人的频率碰到它。这些示例通常都很混乱,以至于很难分离出与此问题相关的功能,但是我最近偶然发现了一个可以很容易地简化为MWE的功能:


library(data.table)

library(lubridate)

library(zoo)


the.table <- data.table(year=1991:1996,var1=floor(runif(6,400,1400)))

the.table[,`:=`(var2=var1/floor(runif(6,2,5)),

                var3=var1/floor(runif(6,2,5)))]


# Replicate data across months

new.table <- the.table[, list(asofdate=seq(from=ymd((year)*10^4+101),

                                           length.out=12,

                                           by="1 month")),by=year]


# Do a complicated procedure to each variable in some group.

var.names <- c("var1","var2","var3")


for(varname in var.names) {

    #As suggested in an answer to Link 3 above

    #Convert the column name to a 'quote' object

    quote.convert <- function(x) eval(parse(text=paste0('quote(',x,')')))


    #Do this for every column name I'll need

    varname <- quote.convert(varname)

    anntot <- quote.convert(paste0(varname,".annual.total"))

    monthly <- quote.convert(paste0(varname,".monthly"))

    rolling <- quote.convert(paste0(varname,".rolling"))

    scaled <- quote.convert(paste0(varname,".scaled"))


    #Perform the relevant tasks, using eval()

    #around every variable columnname I may want

    new.table[,eval(anntot):=

               the.table[,rep(eval(varname),each=12)]]

    new.table[,eval(monthly):=

               the.table[,rep(eval(varname)/12,each=12)]]


当然,此处对数据和变量的特定影响无关紧要,因此,请不要着重于此或提出改进建议以实现在此特定情况下所完成的工作。我正在寻找的是一种通用的工作流程策略,该工作流程将任意复杂的data.table操作过程重复应用于列列表或列列表列表,在变量中指定或作为参数传递给函数,这里的程序必须以编程方式引用的变量/参数命名的列,并可能包括更新,连接,分组呼叫的data.table特殊对象.I,.SD等等; 但是比上面的一种或其他需要频繁使用的工具更简单,更优雅,更短或更易于设计,实施或理解quote-ing和eval-ing。


特别要注意的是,由于过程可能相当复杂,并且涉及到反复更新data.table和引用更新后的列,因此标准lapply(.SD,...), ... .SDcols = ...方法通常不是可行的替代方法。据我所知,eval(a.column.name)用替换每个调用DT[[a.column.name]]也不会简化很多事情,也不能完全正常地data.table工作,因为据我所知,这对其他操作不太有用。


长风秋雁
浏览 1291回答 3
3回答

aluckdog

我只是花时间来完成它并了解工作流程。这对我来说并不自然,但我理解这个主意。我不确定的是它是不自然的,仅仅是因为它对我的使用方式是新的/陌生的,data.table还是因为它实际上是曲折的/真正的不自然的。当然,可能没有自然的方法可以完成我(/我们)试图做的事情。我希望更多的人可以离开他们的想法。
打开App,查看更多内容
随时随地看视频慕课网APP