在 Rcpp-Function 中使用 Bool-Vector 进行子集化(Rcpp 初学者的问题...)

Subsetting using a Bool-Vector in Rcpp-Function (problems of a Rcpp Beginner...)

问题描述(想想成人和儿童价格不同的会员): 我有两个数据集,一个包含年龄和一个代码。第二个数据框 "decodes" 数值代码取决于某人是孩子还是成年人。我知道想要匹配两个数据集中的代码并接收一个向量,其中包含数据集中每个客户的数值。

我可以使用标准 R-functionalities 来完成这项工作,但由于我的原始数据包含数百万个观察结果,我想使用 Rcpp 包加快计算速度。

不幸的是,我没有成功,尤其是如何像在 R 中那样基于逻辑向量执行子集化。我对 Rcpp 很陌生,没有使用 C++ 的经验,所以我可能遗漏了一些非常基础的东西点.

我附上了 R 的最小工作示例,感谢任何类型的帮助或解释!


library(Rcpp)

raw_data = data.frame(
       age = c(10, 14, 99, 67, 87, 54, 12, 44, 22, 8),
       iCode = c("code1", "code2", "code3", "code1", "code4", "code3", "code2", "code5", "code5", "code3"))

decoder = data.frame(
        code = c("code1","code2","code3","code4","code5"),
        kid = c(0,0,0,0,100),
        adult = c(100,200,300,400,500))

#-------- R approach (works, but takes ages for my original data set)
calc_value = function(data, decoder){
y = nrow(data)
for (i in 1:nrow(data)){
   position_in_decoder = (data$iCode[i] == decoder$code)
   if (data$age[i] > 18){
          y[i] = decoder$adult[position_in_decoder]
      }else{
          y[i] = decoder$kid[position_in_decoder]
      }
    }
 return(y)
 }

y = calc_value(raw_data, decoder)

#--------- RCPP approach (I cannot make this one work) :(

cppFunction(
'NumericVector calc_Rcpp(DataFrame df, DataFrame decoder) {
 NumericVector age = df["age"];
 CharacterVector iCode = df["iCode"];
 CharacterVector code = decoder["code"];
 NumericVector adult = decoder["adult"];
 NumericVector kid = decoder["kid"];
 const int n = age.size();
 LogicalVector position;
 NumericVector y(n);

  for (int i=0; i < n; ++i) {
    position = (iCode[i] == code);
    if (age[i] > 18 ) y[i] = adult[position];
    else y[i] = kid[position];
    }
  return y;
  }')

这里没有必要选择 C++。正确使用R:

raw_data = data.frame(
  age = c(10, 14, 99, 67, 87, 54, 12, 44, 22, 8),
  iCode = c("code1", "code2", "code3", "code1", "code4", "code3", "code2", "code5", "code5", "code3"))

decoder = data.frame(
  code = c("code1","code2","code3","code4","code5"),
  kid = c(0,0,0,0,100),
  adult = c(100,200,300,400,500))

foo <- merge(raw_data, decoder, by.x = "iCode", by.y = "code")
foo$res <- ifelse(foo$age > 18, foo$adult, foo$kid)
foo
#>    iCode age kid adult res
#> 1  code1  10   0   100   0
#> 2  code1  67   0   100 100
#> 3  code2  14   0   200   0
#> 4  code2  12   0   200   0
#> 5  code3  54   0   300 300
#> 6  code3  99   0   300 300
#> 7  code3   8   0   300   0
#> 8  code4  87   0   400 400
#> 9  code5  44 100   500 500
#> 10 code5  22 100   500 500

这也适用于大型数据集。