我正在尝试使用准引用语法(quo
,exprs
,!!
等)以及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
被定义为命名列表,所以我根本无法理解错误。可以使用str
和typeof
进行检查。
我尝试了一种略有不同的方式来定义新变量:
log_vars <- unlist(foreach(i = names(data_in[-1]), j = paste0(names(data_in[-1]), "_log")) %do%
exprs(!!j := log10(!!sym(i))))
鉴于unlist
已经提供了一个列表作为输出,因此我必须使用exprs
。无论哪种方式,我都会得到与以前相同的错误。
自然,我希望在数据框中插入10个名为result.1_log, result.2_log
等的新变量。相反,我收到上述错误,并且未创建新的数据框。
我怀疑rx
函数不喜欢使用准引用语法,但是,在必须标识具有某些变量的NA值的主题之前,我曾使用过它。这是使用rowSelection
的{{1}}参数完成的。我确实意识到rxDataStep
需要一个逻辑表达式,而rowSelection
需要一个命名表达式列表。
任何帮助将不胜感激,因为这种类型的数据转换将在我的分析中再次跟上。我确实怀疑我只是不了解准引号语法的内部工作原理,或者可能不了解列表的总体工作原理,但希望有一个简单的解决方法。
我正在使用Microsoft R Open 3.4.3。
我的会话信息如下:
transforms
答案 0 :(得分:0)
我不确定您要做什么,因为我认为您使事情变得太复杂了。 如果您要做的只是获取每个数据点中每个#的日志,那么我在下面显示两种方法。
让我知道我是否完全错过了分数!
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)