【发布时间】:2011-01-16 20:57:27
【问题描述】:
我正在尝试从 R 调用一个程序(C 可执行文件measurementDensities_out 中的函数getNBDensities)。该函数传递了几个数组和变量double runsum。现在,getNBDensities 函数基本上什么都不做:它打印以筛选传递参数的值。我的问题是调用函数的语法:
array(.C("getNBDensities",
hr = as.double(hosp.rate), # a vector (s x 1)
sp = as.double(samplingProbabilities), # another vector (s x 1)
odh = as.double(odh), # another vector (s x 1)
simCases = as.integer(x[c("xC1","xC2","xC3")]), # another vector (s x 1)
obsCases = as.integer(y[c("yC1","yC2","yC3")]), # another vector (s x 1)
runsum = as.double(runsum), # double
DUP = TRUE, NAOK = TRUE, PACKAGE = "measurementDensities_out")$f,
dim = length(y[c("yC1","yC2","yC3")]),
dimnames = c("yC1","yC2","yC3"))
在正确执行函数后(即正确的输出打印到屏幕),我得到的错误是
Error in dim(data) <- dim : attempt to set an attribute on NULL
我不清楚我应该传递函数的维度是多少:它应该是s x 5 + 1(长度为s 的五个向量和一个双倍)?我尝试了各种组合(包括sx5+1),但在网上只发现了看似矛盾的描述/示例,说明这里应该发生的事情。
有兴趣的可以看下C代码:
#include <R.h>
#include <Rmath.h>
#include <math.h>
#include <Rdefines.h>
#include <R_ext/PrtUtil.h>
#define NUM_STRAINS 3
#define DEBUG
void getNBDensities( double *hr, double *sp, double *odh, int *simCases, int *obsCases, double *runsum );
void getNBDensities( double *hr, double *sp, double *odh, int *simCases, int *obsCases, double *runsum ) {
#ifdef DEBUG
for ( int s = 0; s < NUM_STRAINS; s++ ) {
Rprintf("\nFor strain %d",s);
Rprintf("\n\tHospitalization rate = %lg", hr[s]);
Rprintf("\n\tSimulation probability = %lg",sp[s]);
Rprintf("\n\tSimulated cases = %d",simCases[s]);
Rprintf("\n\tObserved cases = %d",obsCases[s]);
Rprintf("\n\tOverdispersion parameter = %lg",odh[s]);
}
Rprintf("\nRunning sum = %lg",runsum[0]);
#endif
}
简单的解决方案
虽然可能存在更好(即可能更快或语法更清晰)的解决方案(请参阅下面 Dirk 的回答),但以下代码简化是可行的:
out<-.C("getNBDensities",
hr = as.double(hosp.rate),
sp = as.double(samplingProbabilities),
odh = as.double(odh),
simCases = as.integer(x[c("xC1","xC2","xC3")]),
obsCases = as.integer(y[c("yC1","yC2","yC3")]),
runsum = as.double(runsum))
变量可以在>out中访问。
【问题讨论】:
-
你的函数没有返回任何东西,那么你为什么要把任何东西都变成数组呢?
-
@hadley:我认为您正在研究这个问题。我正在研究我在代码中调用的另一个 C 函数的示例,它确实操作了一个大数组。这个函数最终只会从数组中读取来计算
runsum,然后我的 R 程序的其余部分将使用它。但是,仅调用out<-(.C("getNBDensities",...))只会为out返回NULL... -
我总是会推荐
.Call()而不是.C()。 -
我的代码实际上已经在其他地方使用了
.C()调用。当我使用Rprof而不是.C()时,.Call()出现在顶部附近——我认为这意味着它已经在内部进行了优化。底线是我的语法很糟糕,我担心如果我无法在这里掌握一个简单的.C()调用,我将无法使用.Call()重写我的其他函数调用。跨度> -
历史上,
.C()排在第一位。但它的功能也受到更多限制。大多数理智的人推荐.Call()。