向 Rcpp::DataFrame 添加列正在回退到列表 [英] Adding column to Rcpp::DataFrame is falling back to list
问题描述
当我使用 Rcpp 向数据帧添加一列时,它在返回后不再呈现为数据帧.我试图尽可能接近添加列的原始示例,但无论我如何对其进行变异,我都会得到一个列表.
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.
如下所示,当我通过分配给新键或使用 push_back()
添加列时,我丢失了对象的类和一些重要属性.
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 此处,或复制下面的输出
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"
(Rcpp 1.0.3 在 Catalina 10.15.1 上为 R 3.6.0)
(R 3.6.0 on Catalina 10.15.1 with Rcpp 1.0.3)
推荐答案
不幸的是,当添加新列时,Rcpp::DataFrame
对象失去了它的 class
属性,抛出它返回到 Rcpp::List
.可以通过添加 Rcpp::Rcout << 在 C++ 中验证这一点.NDF.hasAttribute("class") <
Rcpp::List
显式转换为 Rcpp::DataFrame
很容易:
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
由 reprex 包 (v0.3.0) 于 2019 年 12 月 17 日创建
Created on 2019-12-17 by the reprex package (v0.3.0)
这篇关于向 Rcpp::DataFrame 添加列正在回退到列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!