在C循环中增长R矩阵

在C循环中增长R矩阵,c,r,matrix,C,R,Matrix,我有一个生成一系列数据向量的例程,每次迭代一次。我想找到一种方法来“增长”包含这些向量的列表或矩阵。我试图创建一个列表 PROTECT( myList = allocVector( VECSXP, 1 ) ) 但是,有没有一种方法可以通过在最后推一个向量元素来增加列表 也不介意使用矩阵,因为我生成的向量长度相同。 这是C++在C上下手的一个很好的例子。 在C++中,可以使用STL容器(如vector),并且可以使用 PurthObjor()/

我有一个生成一系列数据向量的例程,每次迭代一次。我想找到一种方法来“增长”包含这些向量的列表或矩阵。我试图创建一个列表

PROTECT( myList = allocVector( VECSXP, 1 ) )
但是,有没有一种方法可以通过在最后推一个向量元素来增加列表


也不介意使用矩阵,因为我生成的向量长度相同。

这是C++在C上下手的一个很好的例子。 <>在C++中,可以使用STL容器(如vector),并且可以使用<代码> PurthObjor()/<代码一次一次插入元素。您从不使用
malloc
free
(或
new
delete
),也从不触摸指针。在C中根本没有办法做到这一点


<>也可以利用R和C++之间的接口,使C++中的数据变得更容易。在
builtin.c:lengthgets
中实现。返回的指针需要保护,因此需要一种模式

SEXP myList;
PROTECT_INDEX ipx;
PROTECT_WITH_INDEX(myList = allocVector( VECSXP, 1 ), &ipx);
REPROTECT(mylist = Rf_lengthgets(mylist, 100), ipx);
如果一个列表是基于某个未知的停止条件增长的,那么该方法可能类似于R中的方法,在预分配和填充之后是扩展;以下是psuedo代码:

const int BUF_SIZE = 100;
PROTECT_INDEX ipx;
SEXP myList;
int i, someCondition = 1;

PROTECT_WITH_INDEX(myList=allocVector(VECSXP, BUF_SIZE), &ipx);
for (i = 0; some_condition; ++i) {
    if (Rf_length(myList) == i) {
        const int len = Rf_length(myList) + BUF_SIZE;
        REPROTECT(myList = Rf_lengthgets(mYlist, BUF_SIZE), &ipx);
    }
    PROTECT(result = some_calculation();
    SET_VECTOR_ELT(myList, i, result);           
    UNPROTECT(1);
    // set some_condition
}
Rf_lengthgets(myList, i); // no need to re-PROTECT; we're leaving C
UNPROTECT(1)
return myList;

这将执行myList的深度复制,因此成本可能会很高,并且在某些方面,如果ht emain客观地评估某些_计算,那么在R循环中执行预分配和扩展操作似乎更容易,效率也不会太低,调用一些计算和循环内的分配。

我有几个C++建议给你…谢谢。不过,C++不是一种选择。我使用C代码作为FORTRAN的包装器,就像所有这些程序一样,实际上,我以迭代的方式评估R对象。需要包装Fortran不排除使用C++。但是我不选择在这个项目上使用C++。这种方法的问题是,一旦我再次调用C过程,就无法“保存”变量长度。事实上,我要推送到列表中的数据向量是用Fortran代码生成的;我保存它们的唯一方法是将它们推送到一个列表中,该列表在此类数据向量第一次到达时在R环境中创建,或者从R环境中读取并推送到列表的最后一个位置。所以也许我的问题应该是,“有没有办法把向量推到由R环境引入C的列表的最后一个位置”?我不确定我是否理解你的意思;我尝试添加一个示例,使用可以从R对象获得的关于其长度的信息。谢谢Martin。但它应该更简单:
sexpmylist,newElement;PROTECT(mylist=findVarInFrame(rho,install(“myRList”));//mylist的长度为n;我想向其中添加新元素,并将其返回到R PROTECT(newElement=allocVector(REALSXP,5));//将新元素推到mylist defineVar的末尾(install(“myRList”),mylist,rho))与使用相同方法从R读取的矩阵中添加一行相同。我不建议这样做。您希望C代码的行为类似于R函数调用——创建和修改新对象,而不是修改现有对象。也许您想从R传入当前向量,但在更改之前仍然希望复制它。或者您只需返回newElement,并将其添加到R中的现有列表中。