r语言 - Rcpp 函数,用于有条件地将数据框中的特定元素替换为列表列



我正在尝试熟悉Rcpp软件包。我有一个数据框df,我希望将所有小于 6 的值替换为 6,将所有大于 8 的值替换为 8 ...我想保留所有其他值:

>df<-data.frame(w= 1:3, x=3:5, y=6:8, z = I(list(1:2, 1:3, 1:4)))
>df<-as.data.frame(do.call(cbind, 
lapply(df[1:3],
function(x) Map("*", df$z, x)))) 
>df 
w             x             y
1        1, 2          3, 6         6, 12
2     2, 4, 6      4, 8, 12     7, 14, 21
3 3, 6, 9, 12 5, 10, 15, 20 8, 16, 24, 32

我已经尝试了这段代码,它只能部分工作。

library(Rcpp)
DataFrame replace(DataFrame df) {
R_xlen_t nCols = df.cols();
R_xlen_t nRows = df.rows();
List result(nCols * nRows);
result.attr("dim") = Dimension(nRows, nCols);
colnames(result) = as<CharacterVector>(df.names());
for (R_xlen_t i = 0; i < nCols; ++i) {
List column = as<List>(df[i]);
for (R_xlen_t j = 0; j < nRows; ++j) {
NumericVector tmp = as<NumericVector>(column[j]);
if(tmp[j] < 6){
tmp[j] = 6;
} else if(tmp[j] > 8){
tmp[j] = 8;
}else {
tmp[j] = tmp[j];
result[i * nCols + j] =  tmp;
}
}
DataFrame df1(result); 
return df1;
}')
>replace(df)
w            x            y
1        6, 2         6, 6        6, 12
2     2, 6, 6     4, 6, 12     7, 6, 21
3 3, 6, 6, 12 5, 10, 6, 20 8, 16, 6, 32

我希望对代码中的错误有所提示。我的预期输出是:

>out
#           w          x          y
#1       6, 6       6, 6       6, 8
#2    6, 6, 6    6, 8, 8    7, 8, 8
#3 6, 6, 8, 8 6, 8, 8, 8 8, 8, 8, 8

恐怕你忘了循环tmp

library(Rcpp)
cppFunction('
DataFrame replace(DataFrame df) {
R_xlen_t nCols = df.cols();
R_xlen_t nRows = df.rows();
List result(nCols * nRows);
result.attr("dim") = Dimension(nRows, nCols);
colnames(result) = as<CharacterVector>(df.names());
for (R_xlen_t i = 0; i < nCols; ++i) {
List column = as<List>(df[i]);
for (R_xlen_t j = 0; j < nRows; ++j) {
NumericVector tmp = as<NumericVector>(column[j]);
for (R_xlen_t k = 0; k < tmp.size(); k++) {
if(tmp[k] < 6){
tmp[k] = 6;
} else if(tmp[k] > 8){
tmp[k] = 8;
} else {
tmp[k] = tmp[k];
}
}
result[i * nCols + j] =  tmp;
}
}
DataFrame df1(result); 
return df1;
}')
df<- data.frame(w= 1:3, x=3:5, y=6:8, z = I(list(1:2, 1:3, 1:4)))
df <- as.data.frame(do.call(cbind, lapply(df[1:3], function(x) Map("*", df$z, x))))
replace(df)

然后我们得到了

> df
w             x             y
1        1, 2          3, 6         6, 12
2     2, 4, 6      4, 8, 12     7, 14, 21
3 3, 6, 9, 12 5, 10, 15, 20 8, 16, 24, 32
> replace(df)
w          x          y
1       6, 6       6, 6       6, 8
2    6, 6, 6    6, 8, 8    7, 8, 8
3 6, 6, 8, 8 6, 8, 8, 8 8, 8, 8, 8

最新更新