无法将 R 分析输出移回 Python (rpy2)

Unable to move R analyses output back to Python (rpy2)

我正在尝试将一些数据从 python 传递到 R,然后将结果返回到 python,但似乎无法正常工作。

我成功地将我的数据传递给 R 并且 运行 我对数据的自定义函数甚至得到了输出。我被卡住的地方是将统计输出作为数据框返回到 python 中。我尝试过使用 rpy2,甚至将其导出到 .csv 文件以重新导入,但两种方法都不起作用。当我尝试将其推回到 pandas 时,我收到一个无法强制的错误。当谈到保存到 .csv 时,我似乎无法使用我的“结果”对象让它工作。在阅读中,似乎检查 R 全局环境中的内容可能会帮助我弄清楚,但我也无法弄清楚该怎么做。

感谢任何有用的评论。


#import statements
import rpy2
print(rpy2.__version__)
import rpy2.robjects as robjects
from rpy2.robjects.packages import importr
import rpy2.robjects.numpy2ri
rpy2.robjects.numpy2ri.activate()
base = importr('base')
utils = importr('utils')
name = 'test_subject'

#Sample data to analyze
list1 = [0,1,2,3,4,5,6,7,8,9,10] # analysis window
list2 = [1,5,6,8,7,9,10,8,7,6,3] # nnumber of responses per bin

#Convert data to R objects
set1 = robjects.IntVector(list1)
set2 = robjects.IntVector(list2)

makeDataFrame = robjects.r('''data.frame ''')
df = makeDataFrame(x = set1, y = set2)


# Create curve fitting function
curve_fit = robjects.r('''
curve_fit <- function(df, plot = FALSE){ control <- nls.control(maxiter = 1000, tol = 0.000100, minFactor = 1/2064,
                         printEval = FALSE, warnOnly = TRUE)
  
  fit <- nls(y ~ d+a*exp(-.5*((x-t0)/b)^2)+c*(x-t0), 
             data = df,
             start = list(a = 1, b = 10, t0 = 10, c = 1, d = 1),
             algorithm = "port",
             control = control)
  
  if (plot){
    fitFnc <- function(x) predict(fit, list(x=x))
    par(mfrow = c(1, 1))
    plot(df$x, df$y, xlim = c(0,45))
    curve(fitFnc, from=.5, to=45, add = TRUE)
  }

  return(list("params" = summary(fit), 
              "r2" = cor(predict(fit), df$y)^2))
              }''')

#run function on data
results = curve_fit(df, plot = True)

#Show Results
print('results', results)
print(type(results))

问题出在

return(list("params" = summary(fit), "r2" = cor(predict(fit), df$y)^2))

列表“params”中的第一项是来自 R 的摘要 table。虽然它作为我想要的数据打印在 python 中,但它是单个对象,不能细分为它本质上是 R 输出的图像 table。我需要 return 的是一个数据框,如下面的代码所示。

return(data.frame(coef(summary(fit)), r2 = cor(predict(fit), df$y)^2))

这 return 编辑了一个对象列表,然后我可以将其转换为 numpy 数组并在 python 中进行操作。

这是完整的代码。

#import statements
import rpy2
print(rpy2.__version__)
import rpy2.robjects as robjects
from rpy2.robjects.packages import importr
import rpy2.robjects.numpy2ri
import numpy as np
rpy2.robjects.numpy2ri.activate()
base = importr('base')
utils = importr('utils')




#Sample data to analyze
list1 = [0,1,2,3,4,5,6,7,8,9,10] # analysis window
list2 = [1,5,6,8,7,9,10,8,7,6,3] # nnumber of responses per bin

#Convert data to R objects and place in data frame
set1 = robjects.IntVector(list1)
set2 = robjects.IntVector(list2)

makeDataFrame = robjects.r('''data.frame ''')
df = makeDataFrame(x = set1, y = set2)


# Create curve fitting function in r
curve_fit = robjects.r('''

#Fit function
curve_fit <- function(df, plot = FALSE){ control <- nls.control(maxiter = 1000, tol = 0.000100, minFactor = 1/2064,
                         printEval = FALSE, warnOnly = TRUE)
#Specify formula to fit  
  fit <- nls(y ~ d+a*exp(-.5*((x-t0)/b)^2)+c*(x-t0), 
             data = df,
             start = list(a = 1, b = 10, t0 = 10, c = 1, d = 1),
             algorithm = "port",
             control = control)
             
# Create plot of curve 
  if (plot){
    fitFnc <- function(x) predict(fit, list(x=x))
    par(mfrow = c(1, 1))
    plot(df$x, df$y, xlim = c(0,45))
    curve(fitFnc, from=.5, to=45, add = TRUE)}

    #returns data in R dataframe
  return(data.frame(coef(summary(fit)), r2 = cor(predict(fit), df$y)^2))

               }''')


#run function on data
results = curve_fit(df, plot = True)

results = np.array(results) #convert to numpy array

#Show Results
print('results', results)
print(type(results))