3

请考虑以下示例(使用 2 个 R 会话):

第一个 R 会话 - R 服务器

library(svSocket)
startSocketServer()

第二个 R 会话 - R 客户端

library(svSocket)
con <- socketConnection(host = "localhost", port = 8888, blocking = FALSE)

value<-"setosa"
evalServer(con, tmp, value) # first call to the server
evalServer(con, head(iris[iris$Species==tmp,])) # second call to the server
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

要发送上述查询,我​​需要一个两步过程,首先将参数保存在服务器中,然后使用它们查询表。

问题

只需一步即可。例如,使用pastePHP + MySQL 构建查询并将其发送到服务器。基本上,我需要避免不同的用户tmp在第一次和第二次调用服务器之间覆盖。上述命令将在同时连接 30 到 50 个用户的 Web 应用程序后面运行,所以我认为这种不便可能会发生。

4

1 回答 1

2

一种可能的答案

$ query <- paste0('evalServer(con,"head(iris[iris$Species==\'', value,'\',])")')
$ eval(parse(text=query))
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

这可以完成工作,但它有点像拨号......代码非常混乱且难以阅读。

最终解决方案:

我最终修改/简化了evalServer. 此版本仅接受带有表达式的字符串以在服务器中进行评估

evalServer2 <- function (con, expr) 
{
  if(!is.character(expr)) stop("expr must be a character string containing the expression to evaluate in the server.")
  cat("..Last.value <- try(eval(parse(text = \"", expr, "\"))); .f <- file(); dump(\"..Last.value\", file = .f); flush(.f); seek(.f, 0); cat(\"\\n<<<startflag>>>\", gsub(\"<pointer: [0-9a-fx]+>\", \"NULL\", readLines(.f)), \"<<<endflag>>>\\n\", sep = \"\\n\"); close(.f); rm(.f, ..Last.value); flush.console()\n", 
      file = con, sep = "")
  objdump <- ""
  endloc <- NULL
  while (!length(endloc)) {
    obj <- readLines(con, n = 1000, warn = FALSE)
    if (!length(obj)) {
      Sys.sleep(0.01)
      next
    }
    endloc <- grep("<<<endflag>>>", obj)
    if (length(endloc)) 
      obj <- obj[0:(endloc[length(endloc)] - 1)]
    objdump <- c(objdump, obj)
  }
  startloc <- grep("<<<startflag>>>", objdump)
  if (!length(startloc)) 
    stop("Unable to find <<<startflag>>>")
  objdump <- objdump[-(1:startloc[length(startloc)])]
  nospace <- grep("[^ ]$", objdump)
  nospace <- nospace[nospace < length(objdump)]
  for (i in rev(nospace)) {
    objdump[i] <- paste(objdump[i], objdump[i + 1], sep = "")
    objdump[i + 1] <- ""
  }
  objcon <- textConnection(objdump)
  on.exit(close(objcon))
  source(objcon, local = TRUE, echo = FALSE, verbose = FALSE)
  return(..Last.value)
}

这使得:

> x <- "5 + 4"
> evalServer2(con, x)
[1] 9

相反,evalServer将检索一个名为x存储在 R 服务器中的变量

> evalServer(con, x, 23)
[1] TRUE
> evalServer(con, x)
[1] 23
> evalServer2(con, "x")
[1] 23
于 2014-03-30T13:13:45.727 回答