Adding column to Rcpp::DataFrame is falling back to list

故事扮演 提交于 2021-02-09 06:48:29

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!