我正在使用rscala来传递Scala和R。可以说我有一个Scala函数,该函数返回Array [Double]和Double的Array:
Array(projectedTrainToMatrix,predictedTrain,kernelParam,projection,thresholdsToArray)
其中kernelParam
是Double
类型,其他是Array[Double]
。当我从R运行方法时:
myfit<-s$.cristinahg.ocapis.kdlor$kdlorfit(traindata,trainlabels,kerneltype,params)
我得到myfit
作为
ScalaCachedReference... _: Array[Array[_]]
[Ljava.lang.Object;@b9dfc5a
但是我想访问myfit
数组中的每个值。我试图通过myfit$'(1)'
访问它们,但我得到了这个,而不是所需的Double数组:
function (..., .AS.REFERENCE = NA, .EVALUATE = TRUE, .PARENTHESES = FALSE)
{
args <- list(...)
if (!is.null(names(args)))
stop("Arguments should not have names.")
names <- paste0(rep("$", length(args)), seq_len(length(args)))
header <- mkHeader(args, names)
identifier <- ""
body <- if (inherits(reference, "ScalaInterpreterReference"))
paste0(reference[["identifier"]], ".", method)
else if (inherits(reference, "ScalaCachedReference")) {
if (.EVALUATE) {
identifier <- reference[["identifier"]]
paste0("R.cached($0).asInstanceOf[", reference[["type"]],
"].", method)
}
else {
paste0("R.cached(\\"", reference[["identifier"]],
"\\").asInstanceOf[", reference[["type"]], "].",
method)
}
}
else if (inherits(reference, "ScalaInterpreterItem")) {
if (method == "new")
paste0("new ", reference[["snippet"]])
else paste0(reference[["snippet"]], ".", method)
}
else stop("Unrecognized reference type.")
argsList <- paste0(names, collapse = ",")
if ((nchar(argsList) > 0) || .PARENTHESES)
argsList <- paste0("(", argsList, ")")
snippet <- paste0(header, paste0(body, argsList))
if (get("show.snippet", envir = interpreter[["env"]]))
cat("<<<\\n", snippet, "\\n>>>\\n", sep = "")
cc(interpreter)
wb(interpreter, DEF)
wc(interpreter, snippet)
flush(interpreter[["socketIn"]])
status <- rb(interpreter, "integer")
if (status != OK) {
if (get("serializeOutput", envir = interpreter[["env"]]))
echoResponseScala(interpreter)
stop("Problem defining function.")
}
functionName <- rc(interpreter)
if (get("serializeOutput", envir = interpreter[["env"]]))
echoResponseScala(interpreter)
f <- function(..., .NBACK = 1) {
args <- list(...)
if (length(args) != length(names))
stop("Incorrect number of arguments.")
if (!is.null(names(args)))
stop("Arguments should not have names.")
workspace <- new.env(parent = parent.frame(.NBACK))
assign(".rsI", interpreter, envir = workspace)
for (i in seq_len(length(args))) assign(names[i], args[[i]],
envir = workspace)
cc(interpreter)
wb(interpreter, INVOKE)
wc(interpreter, functionName)
wc(interpreter, identifier)
flush(interpreter[["socketIn"]])
rServe(interpreter, TRUE, workspace)
status <- rb(interpreter, "integer")
if (get("serializeOutput", envir = interpreter[["env"]]))
echoResponseScala(interpreter)
if (status != OK)
stop("Problem invoking function.")
result <- scalaGet(interpreter, "?", .AS.REFERENCE)
if (is.null(result))
invisible(result)
else result
}
if (.EVALUATE)
f(..., .NBACK = 2)
else f
}
<bytecode: 0x55b1ba98b3f8>
<environment: 0x55b1bd2616c0>
那么我如何在R中访问Scala数组的每个元素?
答案 0 :(得分:3)
您的示例显示您正在使用rscala <3.0.0。尽管可以在旧版本中完成,但我建议您使用recent version on CRAN。下面,我提供使用rscala 3.1.0的解决方案。
library(rscala)
scala()
s + '
def kdlorfit(
projectedTrainToMatrix: Array[Double], predictedTrain: Array[Double],
kernelParam: Double, projection: Array[Double], thresholdsToArray: Array[Double]) =
{
Array(projectedTrainToMatrix,predictedTrain,kernelParam,projection,thresholdsToArray)
}
'
x1 <- c(1,2,3)
x2 <- c(11,12,13)
x3 <- 34
x4 <- c(100,110,120)
x5 <- c(50,51)
myfit <- s$kdlorfit(x1,x2,x3,x4,x5)
scalaType(myfit)
identical(x1,myfit(0L)$"asInstanceOf[Array[Double]]"())
identical(x3,myfit(2L)$"asInstanceOf[Double]"())
请注意,由于asInstanceOf
的Scala类型为myfit
,因此需要使用Array[Any]
进行投射。
如果函数返回的是Array[Array[Double]]
而不是Array[Any]
,则不需要强制转换,如下所示。
s + '
def kdlorfit2(
projectedTrainToMatrix: Array[Double],
predictedTrain: Array[Double],
kernelParam: Array[Double],
projection: Array[Double],
thresholdsToArray: Array[Double]) =
{
Array(projectedTrainToMatrix,predictedTrain,kernelParam,projection,thresholdsToArray)
}
'
myfit <- s$kdlorfit2(x1,x2,I(x3),x4,x5)
scalaType(myfit)
identical(x1,myfit(0L))
identical(x3,myfit(2L))
请注意,在调用kdlorfit2
时,参数x3
以Array[Double]
的形式传递,因为它包装在I()
中。如上例所示,它不进行包装就作为Double
传递。