我有一个Web应用程序,其中模块使用工具 rpy2 ,这是为了在python代码中调用和执行R脚本(因为我想增加应用程序模块性)。
我的应用程序有一个客户端 - 服务器arquitecture,它们之间的通信是通过HTTP请求。我必须实现的工具是 Flask 。
现在,我有一个R脚本,它的任务是执行一个集群过程并返回一个以 JSON 格式转换的数据帧,为此我在R中使用了jsonlite。我的问题从这里开始。问题是这个R脚本在python代码中的返回是一个ListVector。
我不知道但是在这种格式下,python会获得R脚本结果。所以我真的不知道如何从python中将这个结果(ListVector)转换为JSON对象,因为最后我需要在我想要公开的服务中返回JSON对象。我试着理解rpy2文档,但对我来说并不清楚rpy2 documentation。
R-脚本
require(kohonen)
require(jsonlite)
group = read.csv2("/home/python_user/Documents/FlaskApp/FlaskApp/resources/data2.csv", header = T, sep = ",", fill = F)
group$X <- NULL
data_train <- group[, -c(3:8)]
###
data_train <- data_train[data_train$NumeroAdultos != 12094,]
data_train$lat <- as.numeric(as.character(data_train$lat))
data_train$lon <- as.numeric(as.character(data_train$lon))
str(data_train)
#### Write JSON K-means #######
cl <- kmeans(data_train, 5)
cl$cluster
result <- data_train[,1:2]
result <- cbind(result, colorCluster = cl$cluster)
result$colorCluster[result$colorCluster == 1] <- "red"
result$colorCluster[result$colorCluster == 2] <- "blue"
result$colorCluster[result$colorCluster == 3] <- "green"
result$colorCluster[result$colorCluster == 4] <- "orange"
result$colorCluster[result$colorCluster == 5] <- "yellow"
toJSON(result, pretty = TRUE)
Main.py
from flask import Flask, send_file, jsonify, send_from_directory, render_template, Blueprint, request
import json
import rpy2.robjects as robjects
@map_module.route("/serviceData")
def service_data():
r = robjects.r
result = r.source(map_module.root_path + "/R/clustering.R")
return result
控制台结果
File "/home/python_user/Documentos/flaskEnv/local/lib/python3.4/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/home/python_user/Documentos/flaskEnv/local/lib/python3.4/site-packages/flask/app.py", line 1615, in full_dispatch_request
return self.finalize_request(rv)
File "/home/python_user/Documentos/flaskEnv/local/lib/python3.4/site-packages/flask/app.py", line 1630, in finalize_request
response = self.make_response(rv)
File "/home/python_user/Documentos/flaskEnv/local/lib/python3.4/site-packages/flask/app.py", line 1740, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "/home/python_user/Documentos/flaskEnv/local/lib/python3.4/site-packages/werkzeug/wrappers.py", line 885, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "/home/python_user/Documentos/flaskEnv/local/lib/python3.4/site-packages/werkzeug/wrappers.py", line 57, in _run_wsgi_app
return _run_wsgi_app(*args)
File "/home/python_user/Documentos/flaskEnv/local/lib/python3.4/site-packages/werkzeug/test.py", line 884, in run_wsgi_app
app_rv = app(environ, start_response)
TypeError: 'ListVector' object is not callable
127.0.0.1 - - [24/Mar/2017 17:32:36] "GET /serviceData HTTP/1.1" 500 -
以下行显示&#34;结果&#34;存储R-script返回的变量,调用R-script时该变量的值是ListVector而不是JSON对象。
result = r.source(map_module.root_path + "/R/clustering.R")
感谢您的阅读。
答案 0 :(得分:1)
我一直试着解决这个问题,我找到了一个对我来说不是最好的解决方案。因此,解决方案是从R-script返回JSON对象,使用python获取并使用库JSON和服务json.load作为列表(python对象)加载。完成后你有一个python对象(作为列表但是JSON结构),所以最后在python中的JSON对象中转换这个列表。记住问题是R-sript在python中返回一个ListVector,而且这个对象在python中不可调用。
最终结果
R-Sript(我纠正了一些事情,但本质或结构是相同的)
# K-means Clustering
require(jsonlite)
# Read the data
group = read.csv2("/home/python_user/Documents/FlaskApp/FlaskApp/resources/data2.csv", header = T, sep = ",", fill = F)
# Prepare the data
group$X <- NULL
group <- group[, -c(3:8)]
group <- group[group$NumeroAdultos != 12094,]
group$lat <- as.numeric(as.character(group$lat))
group$lon <- as.numeric(as.character(group$lon))
# Excute the K-means algorithm
cl <- kmeans(group[,3:9], 5)
# Bind the data with its number cluster
group <- group[,1:2]
group <- cbind(group, colorCluster = cl$cluster)
# Change conventions
group$colorCluster[group$colorCluster == 1] <- "red"
group$colorCluster[group$colorCluster == 2] <- "blue"
group$colorCluster[group$colorCluster == 3] <- "green"
group$colorCluster[group$colorCluster == 4] <- "orange"
group$colorCluster[group$colorCluster == 5] <- "yellow"
# Convert the data frame to JSON object
toJSON(group, pretty=FALSE)
Main.py
from flask import Flask, send_file, jsonify, send_from_directory, render_template, Blueprint, request
import json
import rpy2.robjects as robjects
@map_module.route("/getEntomoClustering", methods=['GET'])
def clustering():
r = robjects.r
dataR = r.source(map_module.root_path + "/R/clustering.R")[0][0]
clusters = json.loads(dataR)
return jsonify(clusters)
控制台结果
[
{
"colorCluster": "red",
"lat": 3.8946,
"lon": -76.2884
},
{
"colorCluster": "red",
"lat": 3.8988,
"lon": -76.2904
},
{
"colorCluster": "red",
"lat": 3.9008,
"lon": -76.2904
},
{
"colorCluster": "red",
"lat": 3.9034,
"lon": -76.2916
},
{
"colorCluster": "red",
"lat": 3.8934,
"lon": -76.2916
},
{
"colorCluster": "red",
"lat": 3.9067,
"lon": -76.2941
},
{
"colorCluster": "red",
"lat": 3.8972,
"lon": -76.2947
},
{
"colorCluster": "red",
"lat": 3.8948,
"lon": -76.2964
},... ]
要考虑到,R-script的结果是一个ListVector,在其中找到用R转换的数据Json,但在python中不是可调用对象。为此我访问,直到这个数据JSON,我知道有JSON结构,所以我使用服务json.load并获取一个列表(python对象),最终再次转换为JSON对象与服务jsonify(此对象可以是用python对象处理,可调用)
dataR = r.source(map_module.root_path + "/R/clustering.R")[0][0] //JSON data from R is not callable
clusters = json.loads(dataR) // load a list, python object
return jsonify(clusters) // convert to JSON object callable
对此解决方案的任何问题都会问我。 谢谢你的阅读。
答案 1 :(得分:0)
首先将R数据帧转换为pandas数据帧;从那里,它更容易转换为json格式。
import pandas as pd
import rpy2.robjects as robjects
from rpy2.robjects import pandas2ri
iris_r = robjects.r("data(iris);iris")
iris_pd = pandas2ri.ri2py(iris_r)