<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">I come late to this discussion, but it should be pointed out that using "sprintf" without ensuring that your buffer is long enough is not a "subtlety" but a bug.<div><br></div><div>A more "C++ way" to do it, and most importantly safer, would be to use std::ostringstream:</div><div><br></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><div>for (int i = 0; i < nrows; i++) {</div><div> std::ostringstream rowname;</div><div> rowname << i;</div><div> row_names(j) = rowname;</div><div>}</div><div>for (int j = 0; j < ncols; j++) {</div><div> std::ostringstream colname;</div><div> colname << < "X." << j;</div><div> col_names(j) = colname;</div><div>}</div></blockquote><div><br></div><div>Davor</div><div><br></div><div><br></div><div><div><div>On 2013-01-18, at 3:25 PM, John Merrill wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; ">Sure. I'll write something up for the gallery, but here's the crude outline.<div><br></div><div>Here's the C++ code:</div><div><pre><font color="#000000">#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List BuildCheapDataFrame(List a) {
List returned_frame = clone(a);
GenericVector sample_row = returned_frame(1);
StringVector row_names(sample_row.length());
for (int i = 0; i < sample_row.length(); ++i) {
char name[5];
sprintf(&(name[0]), "%d", i);
row_names(i) = name;
}
returned_frame.attr("row.names") = row_names;
StringVector col_names(returned_frame.length());
for (int j = 0; j < returned_frame.length(); ++j) {
char name[6];
sprintf(&(name[0]), "X.%d", j);
col_names(j) = name;
}
returned_frame.attr("names") = col_names;
returned_frame.attr("class") = "data.frame";
return returned_frame;
}</font></pre>There are some subtleties in this code:</div><div><br></div><div>* It turns out that one can't send super-large data frames to it because of possible buffer overflows. I've never seen that problem when I've written Rcpp functions which exchanged SEXPs with R, but this one uses Rcpp:export in order to use sourceCpp.</div><div>* Notice the invocation of clone() in the first line of the code. If you don't do that, you wind up side-effecting the parameter, which is not what most people would expect.</div></span><br class="Apple-interchange-newline"></blockquote></div><br></div></body></html>