Rcpp question about getting a sub CharacterVector. I have made a rolling window style function that works on multiple NumericVectors, but fails to work when I include CharacterVectors. I get this error each time I try to use a CharacterVector: "taking address of temporary object type proxy".
This is the line of code that causes the problem:
CharacterVector subchrom (&chrom[i], &chrom[i+4]);
I am a C++ novice, and thus the solution is beyond me at the moment. From what I have read, the issue is in using the pointer "&" for two different types of vectors, but I don't understand how to fix this. Would someone mind giving me a hand solving this error?
I did a little more reading and now I have a second question. Are "CharacterVectors" in Rcpp programmed as a proxy? This is the only vector type I have this issue with. What is the best workaround?
Here is a full example:
#example data for R
start <- c(0, 2, 4, 6, 8, 10)
chrom <- c("chr1", "chr1", "chr1", "chr1", "chr1", "chr1")
df <- data.frame(start, chrom)
This is the .cpp Rcpp program:
#include <algorithm>
#include <Rcpp.h>
#include <vector>
using namespace Rcpp;
// [[Rcpp::export]]
List modifyDataFrame2(DataFrame df) {
// access the columns
CharacterVector chrom = df["chrom"];
IntegerVector start = df["start"];
List Out = List::create();
// write the for loop
for(int i=0; i < df.nrow(); ++i){
NumericVector substart (&start[i], &start[i+4]);
CharacterVector subchrom (&chrom[i], &chrom[i+4]);
Rcout << "substart is:" <<substart << "\n";
Rcout << "subchrom is:" <<subchrom << "\n";
List temp = List::create(subchrom, substart);
Out.push_back(temp);
}
return Out;
}
I am trouble shooting the window function at the moment, hence why it doesn't do anything except print the subvectors. I want to get my input and output from c++ dialed before I complicate things with calculations.
Thank you for your help. I greatly appreciate your time.
You are making some somewhat heroic assumptions about what you think Rcpp should support. Sadly, it doesn't always work that way with code and libraries.
These "flexible" subsetters are not the strongest are of Rcpp but some are supported. But you need to look at what is actually supported -- I just reminded myself by looking at existing tests for subsetting. And one of the oldest methods is indexing by another vector. As you always want four elements, I just create an index vector ... and then add i
to it.
Modified code (also corrected on IntegerVector
to NumericVector
confusion, and changing the indexing):
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List modifyDataFrame2(DataFrame df) {
// access the columns
CharacterVector chrom = df["chrom"];
IntegerVector start = df["start"];
List Out;
IntegerVector ind = IntegerVector::create(0,1,2,3);
// write the for loop
for(int i=0; i < df.nrow()-3; ++i){
IntegerVector currind = ind + i;
IntegerVector substart = start[currind];
CharacterVector subchrom = chrom[currind];
Rcout << "substart is:" << substart << "\n";
Rcout << "subchrom is:" << subchrom << "\n";
List temp = List::create(subchrom, substart);
Out.push_back(temp);
}
return Out;
}
/*** R
#example data for R
start <- c(0, 2, 4, 6, 8, 10)
chrom <- c("chr1", "chr1", "chr1", "chr1", "chr1", "chr1")
df <- data.frame(start, chrom)
modifyDataFrame2(df)
*/
And when I sourceCpp()
this we get the following:
R> Rcpp::sourceCpp("~/git/stackoverflow/54190760/answer.cpp")
R> #example data for R
R> start <- c(0, 2, 4, 6, 8, 10)
R> chrom <- c("chr1", "chr1", "chr1", "chr1", "chr1", "chr1")
R> df <- data.frame(start, chrom)
R> modifyDataFrame2(df)
substart is:0 2 4 6
subchrom is:"chr1" "chr1" "chr1" "chr1"
substart is:2 4 6 8
subchrom is:"chr1" "chr1" "chr1" "chr1"
substart is:4 6 8 10
subchrom is:"chr1" "chr1" "chr1" "chr1"
[[1]]
[[1]][[1]]
[1] "chr1" "chr1" "chr1" "chr1"
[[1]][[2]]
[1] 0 2 4 6
[[2]]
[[2]][[1]]
[1] "chr1" "chr1" "chr1" "chr1"
[[2]][[2]]
[1] 2 4 6 8
[[3]]
[[3]][[1]]
[1] "chr1" "chr1" "chr1" "chr1"
[[3]][[2]]
[1] 4 6 8 10
R>