【问题标题】:Rcpp subsetting rows of DataFrameDataFrame 的 Rcpp 子集行
【发布时间】:2016-11-19 10:32:34
【问题描述】:

我希望使用Rcpp 包创建iris 数据集的以下子集:

head(subset(iris, Species == "versicolor"))

  Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
51          7.0         3.2          4.7         1.4 versicolor
52          6.4         3.2          4.5         1.5 versicolor
53          6.9         3.1          4.9         1.5 versicolor
54          5.5         2.3          4.0         1.3 versicolor
55          6.5         2.8          4.6         1.5 versicolor
56          5.7         2.8          4.5         1.3 versicolor

我知道如何对 Rcpp::DataFrame 的列进行子集化 - 有一个重载运算符 [,其工作方式与 R:x["var"] 一样。但是,我找不到任何方法可以让我对具有不固定列数的 DataFrame 的行进行子集化。

我想编写一个函数subset_rows_rcpp_iris,它接受Rcpp::DataFrame(总是虹膜)和CharacterVector level_of_species作为输入。它将返回DataFrame 对象。

DataFrame subset_rows_rcpp_iris(DataFrame x, CharacterVector level_of_species) {
    ...
}

首先,我想找到满足逻辑查询的行索引。我的问题是,如果我在test 函数中访问Species 向量,将其保存为CharacterVector,然后将其与level_of_species 进行比较,在setosa 和FALSE 的情况下,我总是只得到一个TRUE 值其他情况下的值。

cppFunction('
    LogicalVector test(DataFrame x, CharacterVector level_of_species) {
            CharacterVector sub = x["Species"];
            LogicalVector ind = sub == level_of_species;
            return(ind);
            }
')
head(test(iris, "setosa"))

[1]  TRUE FALSE FALSE FALSE FALSE FALSE

如果可行,我可以重写 test 函数并使用具有 TRUE/FALSE 值的向量分别对数据框的每一列进行子集化,然后将它们再次与 Rcpp::DataFrame::create 组合。

【问题讨论】:

  • 是的,确实如此。但是,我不知道如何在 C++ 中表示字符标量。 Rcpp中没有CharacterScalar这样的类。 String 也不起作用。
  • 对对对!!我的错误..因为有 NumericScalar 我在这里也有同样的想法....我想我们在做 sub==level_of_species 时假设我们在这里用 C++ 循环使用 R
  • 我们需要一个for循环

标签: r rcpp


【解决方案1】:
cppFunction('LogicalVector test(DataFrame x, StringVector level_of_species) {
  using namespace std;  
  StringVector sub = x["Species"];
  std::string level = Rcpp::as<std::string>(level_of_species[0]);
  Rcpp::LogicalVector ind(sub.size());
  for (int i = 0; i < sub.size(); i++){
      ind[i] = (sub[i] == level);
  }

  return(ind);
}')

xx=test(iris, "setosa")
> table(xx)
 xx
 FALSE  TRUE 
   100    50 

子集完成!!! (我自己从这个问题中学到了很多......谢谢!)

cppFunction('Rcpp::DataFrame test(DataFrame x, StringVector level_of_species) {
  using namespace std;  
  StringVector sub = x["Species"];
  std::string level = Rcpp::as<std::string>(level_of_species[0]);
  Rcpp::LogicalVector ind(sub.size());
  for (int i = 0; i < sub.size(); i++){
    ind[i] = (sub[i] == level);
  }

 // extracting each column into a vector
 Rcpp::NumericVector   SepalLength = x["Sepal.Length"];
 Rcpp::NumericVector   SepalWidth = x["Sepal.Width"];
 Rcpp::NumericVector PetalLength = x["Petal.Length"];
 Rcpp::NumericVector   PetalWidth = x["Petal.Width"];


 return Rcpp::DataFrame::create(Rcpp::Named("Sepal.Length")  = SepalLength[ind],
                                Rcpp::Named("Sepal.Width")  = SepalWidth[ind],
                                Rcpp::Named("Petal.Length")  = PetalLength[ind],
                                Rcpp::Named("Petal.Width")  = PetalWidth[ind]
);}')

yy=test(iris, "setosa")
> str(yy)
 'data.frame':  50 obs. of  4 variables:
 $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
 $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
 $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
 $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    • 2013-10-14
    • 2018-03-30
    • 2019-02-15
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    相关资源
    最近更新 更多