Skip to content

Instantly share code, notes, and snippets.

@artemklevtsov
Last active September 27, 2019 07:05
Show Gist options
  • Save artemklevtsov/83fe996a9b446566fe9c40137f53a8b3 to your computer and use it in GitHub Desktop.
Save artemklevtsov/83fe996a9b446566fe9c40137f53a8b3 to your computer and use it in GitHub Desktop.
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export(rng = false)]]
List df2list(const DataFrame& x) {
std::size_t nrows = x.rows();
std::size_t ncols = x.cols();
CharacterVector nms = x.names();
List res(no_init(nrows));
for (std::size_t i = 0; i < nrows; ++i) {
List tmp(no_init(ncols));
tmp.names() = nms;
for (std::size_t j = 0; j < ncols; ++j) {
switch(TYPEOF(x[j])) {
case LGLSXP:
case INTSXP: {
tmp[j] = as<LogicalVector>(x[j])[i];
break;
}
case REALSXP: {
tmp[j] = as<NumericVector>(x[j])[i];
break;
}
case STRSXP: {
tmp[j] = as<std::string>(as<CharacterVector>(x[j])[i]);
break;
}
case VECSXP: {
tmp[j] = as<List>(x[j])[i];
break;
}
default: stop("Unsupported type '%s'.", type2name(x));
}
}
res[i] = tmp;
}
return res;
}
template <typename T>
void cp(List& l, const T& v, std::size_t n, std::size_t idx) {
for (std::size_t i = 0; i < n; ++i) {
List tmp = as<List>(l[i]);
tmp[idx] = v[i];
}
}
// [[Rcpp::export(rng = false)]]
List df2list2(const DataFrame& x) {
std::size_t nrows = x.rows();
std::size_t ncols = x.cols();
CharacterVector nms = x.names();
List res(no_init(nrows));
for (std::size_t i = 0; i < nrows; ++i) {
List l(no_init(ncols));
l.names() = nms;
res[i] = l;
}
for (std::size_t j = 0; j < ncols; ++j) {
switch(TYPEOF(x[j])) {
case LGLSXP:
case INTSXP: {
cp(res, as<IntegerVector>(x[j]), nrows, j);
break;
}
case REALSXP: {
cp(res, as<NumericVector>(x[j]), nrows, j);
break;
}
case STRSXP: {
cp(res, as<std::vector<std::string>>(x[j]), nrows, j);
break;
}
case VECSXP: {
cp(res, as<List>(x[j]), nrows, j);
break;
}
default: stop("Unsupported type '%s'.", type2name(x));
}
}
return res;
}
/***R
data("Batting", package = "Lahman")
x <- Batting[1:10000, 1:10]
# str(df2list2(x))
# df2list2(iris)
bench::mark(
df2list(x),
df2list2(x),
purrr::transpose(x)
)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment