【问题标题】:rxDataStep "transform" argument using quasi-quotationrxDataStep 使用准引号“转换”参数
【发布时间】:2019-05-23 18:56:07
【问题描述】:

我正在尝试使用准引号语法(quoexprs!! 等)以及 foreach 函数通过表达式的命名列表创建几个新变量在rxDataStep 函数内进行评估,具体来说,是transforms 参数。我收到以下错误:

Error in rxLinkTransformComponents(transforms = transforms, transformFunc = transformFunc,  : 'transforms' must be of the form list(...)

我有一个数据集,其中包含许多变量,我需要进行对数转换才能执行进一步分析。我已经使用“RevoScaleR”包中的rx 函数大约三年了,完全错过了数据转换技术的“tidyverse”/管道方法。我偶尔会涉足这些工具,但更喜欢坚持使用前面提到的 rx 函数,因为我相对熟悉,而且到目前为止它们对我很有帮助。


作为 MWE:

所需的库:

library(foreach)
library(rlang)

创建需要对数转换的变量。

vars <- foreach(i = 10:20, .combine = "cbind") %do% rnorm(10, i)

带有标识符和以上变量的数据框。

data_in <- data.frame(id = 1:10, vars)

创建对数转换变量表达式的对象;这将创建一个命名列表。

log_vars <- foreach(i = names(data_in[-1]), .final = function(x) set_names(x, paste0(names(data_in[-1]), "_log"))) %do%
expr(log10(!!sym(i)))

现在尝试将变量添加到现有数据框。

data_out <- rxDataStep(inData = data_in, transforms = log_vars, transformObjects = list(log_vars = log_vars))

产生的错误如下:

Error in rxLinkTransformComponents(transforms = transforms, transformFunc = transformFunc,  :  'transforms' must be of the form list(...)

鉴于log_vars 被定义为命名列表,我根本无法理解错误。可以通过strtypeof 进行检查。

我尝试了一种稍微不同的方式来定义新变量:

log_vars <- unlist(foreach(i = names(data_in[-1]), j = paste0(names(data_in[-1]), "_log")) %do%
exprs(!!j := log10(!!sym(i))))

鉴于exprs 已经提供了一个列表作为输出,我必须使用unlist。无论哪种方式,我都会遇到与以前相同的错误。

当然,我希望在数据框中插入 10 个名为 result.1_log, result.2_log 等的新变量。相反,我收到了上述错误,并且没有创建新的数据框。


我怀疑rx 函数不喜欢使用准引号语法,但是,我之前在必须识别具有某些变量的 NA 值的主题时使用过它。这是使用rxDataSteprowSelection 参数完成的。我确实意识到rowSelection 需要一个单一的逻辑表达式,而transforms 需要一个命名的表达式列表。

任何帮助将不胜感激,因为这种类型的数据转换将在我的分析中再次跟上。我确实怀疑我根本不了解准引号语法的内部工作原理,或者列表的一般工作原理,但希望有一个简单的解决方法。

我正在使用 Microsoft R Open 3.4.3。


我的会话信息如下:

R Services Information: Local R: C:\Program Files\Microsoft\ML Server\R_SERVER\ Version: 1.3.40517.1016 Operating System: Microsoft Windows 10.0.17134 CPU Count: 4 Physical Memory: 12169 MB, 6810 MB free Virtual Memory: 14025 MB, 7984 MB free Video controller[1]: Intel(R) HD Graphics 620 GPU[1]: Intel(R) HD Graphics Family Video memory[1]: 1024 MB Connected users: 1

【问题讨论】:

    标签: r microsoft-r quasiquotes


    【解决方案1】:

    我不太确定你想做什么,因为我认为你把事情弄得太复杂了。 如果您只想记录每个数据点中每个 # 的日志,那么我将在下面展示两种方法。

    1. 方法 #1 是静态的,您知道固定的列数并对其进行硬编码。 rxDataStep 以这种方式运行会快一些。
    2. 方法 #2 更加动态,利用了 transformFunc。 transformFunc 以块的形式工作,因此可以以集群方式安全使用。 rxDataStep 知道如何将块集成在一起。但它的性能会受到一点影响。
    3. 您可能一直在尝试寻找一种混合方法 - 为 rxDataStep 中的 transforms 参数动态构建列表。我还没有找到让它工作的方法。这是在 rxSetVarInfo (Change a dynamic variable name with rxSetVarInfo) 中执行此操作的类似问题,但使用该方法尚未对我产生成功。

    如果我完全错过了标记,请告诉我!

    library(foreach)
    library(rlang)
    
    startSize <- 10
    endSize <- 20
    vars <- foreach(i = startSize:endSize, .combine = "cbind") %do% rnorm(10, i)
    
    data_in <- data.frame(vars)
    tempInput <- tempfile(fileext = ".xdf")
    tempOutput <- tempfile(fileext = ".xdf")
    
    rxImport(inData = data_in, outFile = tempInput, overwrite = T)
    rxGetInfo(tempInput, getVarInfo = T)
    
    ### Approach #1
    print("Approach #1")
    
    rxDataStep(inData = tempInput, outFile = tempOutput, overwrite = T,
           transforms = list(
             log_R1 = log10(result.1),
             log_R2 = log10(result.2),
             log_R3 = log10(result.3),
             log_R4 = log10(result.4),
             log_R5 = log10(result.5),
             log_R6 = log10(result.6),
             log_R7 = log10(result.7),
             log_R8 = log10(result.8),
             log_R9 = log10(result.9),
             log_R10 = log10(result.10),
             log_R11 = log10(result.11)))
    
    rxGetInfo(tempOutput, getVarInfo = T)
    
    ### Approach #2
    print("Approach #2")
    
    logxform <- function(dataList) {
      numRowsInChunk <- length(dataList$result.1)
    
      for (j in 1:columnDepth) { 
        dataList[[paste0("log_R",j)]] <- rep(0, times=numRowsInChunk)
        for (i in 1:numRowsInChunk) {
         dataList[[paste0("log_R",j)]][i] <- log10(dataList[[paste0("result.",j)]][i])
        }
      }
      return(dataList)
    }
    rxDataStep(inData = tempInput, outFile = tempOutput, overwrite = T,
               transformObjects = list(columnDepth = endSize - startSize + 1), 
               transformFunc = logxform)
    
    rxGetInfo(tempOutput, getVarInfo = T)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-16
      • 2020-12-22
      • 2017-08-05
      • 2011-05-11
      相关资源
      最近更新 更多