RCPP函数有条件地用列表列替换数据框中的特定元素

时间:2018-07-07 23:02:18

标签: r for-loop dataframe 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

1 个答案:

答案 0 :(得分:3)

恐怕您忘了循环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