在 Rcpp-Function 中使用布尔向量的子集(Rcpp 初学者的问题..)



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

我可以使用标准的 R 功能来完成这项工作,但由于我的原始数据包含数百万个观察结果,我想使用 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

这也适用于大型数据集。

最新更新