向 Rcpp::DataFrame 添加列正在回退到列表 [英] Adding column to Rcpp::DataFrame is falling back to list

查看:47
本文介绍了向 Rcpp::DataFrame 添加列正在回退到列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆