问题
When I add a column to a dataframe using Rcpp it ceases to be rendered as a dataframe once returned. I'm trying to stay as close to the original examples of adding a column as possible, but I get a list regardless of how I mutate it.
As you can see below, I'm losing the class and some important attributes on the object when I add a column either via assigning to a new key or using push_back()
.
Runnable reprex here, or output copied below
fun <- Rcpp::cppFunction('
List DataFrameExample() {
Rcpp::IntegerVector a = {1, 2, 3};
// create a new data frame
Rcpp::DataFrame DF = Rcpp::DataFrame::create(
Rcpp::Named("a1")=a
);
Rcpp::DataFrame NDF = clone(DF);
//NDF.push_back(a, "a2");
NDF["a2"] = a;
return(Rcpp::List::create(
Rcpp::Named("origDataFrame")=DF,
Rcpp::Named("newDataFrame")=NDF)
);
}')
dfs <- fun()
dfs
## $origDataFrame
## a1
## 1 1
## 2 2
## 3 3
##
## $newDataFrame
## $newDataFrame$a1
## [1] 1 2 3
##
## $newDataFrame$a2
## [1] 1 2 3
lapply(dfs, class)
## $origDataFrame
## [1] "data.frame"
##
## $newDataFrame
## [1] "list"
lapply(dfs, attributes)
## $origDataFrame
## $origDataFrame$names
## [1] "a1"
##
## $origDataFrame$class
## [1] "data.frame"
##
## $origDataFrame$row.names
## [1] 1 2 3
##
##
## $newDataFrame
## $newDataFrame$names
## [1] "a1" "a2"
(R 3.6.0 on Catalina 10.15.1 with Rcpp 1.0.3)
回答1:
Unfortunately a Rcpp::DataFrame
object looses its class
attribute when a new column is added, throwing it back to a Rcpp::List
. One can verify this in C++ by adding Rcpp::Rcout << NDF.hasAttribute("class") << std::endl;
before and after adding the new column. Fortunately, it is easy to turn a Rcpp::List
into a Rcpp::DataFrame
explicitly:
fun <- Rcpp::cppFunction('
List DataFrameExample() {
Rcpp::IntegerVector a = {1, 2, 3};
// create a new data frame
Rcpp::DataFrame DF = Rcpp::DataFrame::create(
Rcpp::Named("a1")=a
);
Rcpp::DataFrame NDF = clone(DF);
Rcpp::Rcout << NDF.hasAttribute("class") << std::endl;
//NDF.push_back(a, "a2");
NDF["a2"] = a;
Rcpp::Rcout << NDF.hasAttribute("class") << std::endl;
return(Rcpp::List::create(
Rcpp::Named("origDataFrame") = DF,
Rcpp::Named("newDataFrame") = Rcpp::DataFrame(NDF))
);
}')
dfs <- fun()
#> 1
#> 0
dfs
#> $origDataFrame
#> a1
#> 1 1
#> 2 2
#> 3 3
#>
#> $newDataFrame
#> a1 a2
#> 1 1 1
#> 2 2 2
#> 3 3 3
Created on 2019-12-17 by the reprex package (v0.3.0)
来源:https://stackoverflow.com/questions/59365294/adding-column-to-rcppdataframe-is-falling-back-to-list