简体   繁体   中英

How do I get a vector to output from C++ into R

Im just starting off on my c++ journey after doing some foundational work in R. We are currently working on how to call C++ functions in R using wrappers etc. I want to feed the c++ function a vector and the length of the vector, and receive whether each element of the vector is positive, negative or zero.

I have a piece of code that works perfectly fine on its own in C++:

#include <iostream>

int main()
{
int vec1[] = {1,-1,0};
int output[3]; 

for ( int i = 0; i < 3; i++) { //for loop to go through each element in vector
        if (vec1[i] < 0){
            output[i] = -1;
        } else if (vec1[i] == 0){
            output[i] = 0;
        } else {
            output[i] = 1;
        }
    }  
    
    std::cout << output[0];
    std::cout << output[1];
    std::cout << output[2];
    return 0;
  
}

However I want to be able feed this code a vector from within R. I got this far on the code, but I am having a little trouble understanding how the pointers work. I want the output to be a single vector 'output'

I got this far but cant figure out how to link the output vector to the dummy parameter. Note that I can't use RCPP for this task.

extern "C" {
  
  void signC( double *vec1 , int *len, double *output ) 
  {
     int outputvec[*len];  
       
    for ( int i = 0; i < *len; i++) { //for loop to go through each element in vector
        if (vec1[i] < 0){
            outputvec[i] = -1;
        } else if (vec1[i] == 0){ // classify as positive/negative/zero
            outputvec[i] = 0;
        } else {
            outputvec[i] = 1;
        }
    }
  } *output = outputvec
}

Would love some feedback - or even links to further reading.

Thanks!!

Rcpp allows you to focus on your code by taking care of the boilerplate. If we write the following file -- which is essentially your main() turned into a 'take a vector, return a vector' function

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::IntegerVector testfunc(Rcpp::IntegerVector vec1) {
    int n = vec1.size();
    Rcpp::IntegerVector output(n);
    for (int i = 0; i < n; i++) { //for loop to go through each element in vector
        if (vec1[i] < 0){
            output[i] = -1;
        } else if (vec1[i] == 0){
            output[i] = 0;
        } else {
            output[i] = 1;
        }
    }
    return output;
}

/*** R
vec <- c(-1L, -1L, 0L)
testfunc(vec)
*/

then by just calling Rcpp::sourceCpp() on it, we get function compiled, linked, loaded --- and even execute the demo at the bottom:

> Rcpp::sourceCpp("~/git/stackoverflow/68010619/answer.cpp")

> vec <- c(-1L, -1L, 0L)

> testfunc(vec)
[1] -1 -1  0
> 

We could make the 'it really assigned it' part stronger by multiplying with a scalar, I suppose.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM