在rcpp中按名称更改矢量元素

问题描述 投票:1回答:2

我有一个函数,我需要创建一个表(tab,然后更改一个值 - tab.names() == k的值,其中k在函数调用中给出。

看看http://dirk.eddelbuettel.com/code/rcpp/Rcpp-quickref.pdf,我希望下面的代码可以工作(用变量名替换"foo"),但我想这需要元素名称是静态的,而我的不是。我已经尝试过使用which,但是无法编译(从'char'无效转换为'Rcpp :: traits :: storage_type <16> :: type {aka SEXPREC *}' - 所以我在那里做错了。

#include <RcppArmadillo.h>
#include <algorithm>
//[[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;

// [[Rcpp::export]]
IntegerVector fun(const arma::vec& assignment, int k) {

  // count number of peptides per protein
  IntegerVector tab = table(as<IntegerVector>(wrap(assignment)));
  CharacterVector all_proteins = tab.names(); 

  char kc = '0' + k;

  // what I need a working version of: 
  tab(kc) = 1;  // gets ignored, as does a [] version of the same thing.
  // or
  tab('0' + k) = 1; // also ignored

  int ki = which(all_proteins == kc); // gives me compile errors

  // extra credit
  // tab.names(k-1) = "-1";

  return tab;
}

/*** R
set.seed(23)
  x <- rpois(20, 5)
  k <- 5

  fun(x, k)

  # same thing in R:
  expected_output <- table(x)
  expected_output # before modification
#  x
#   3  4  5  6  7  9 10 12 
#   2  4  3  3  4  2  1  1 

  expected_output[as.character(k)] <- 1 # this is what I need help with
  expected_output

#  x
#   3  4  5  6  7  9 10 12 
#   2  4  1  3  4  2  1  1 

  # extra credit:
  names(expected_output)[as.character(k)] <- -1

*/

我还在学习rcpp,更重要的是,还在学习如何阅读手册页并将正确的搜索条件插入google / stackoverflow。我确信这是基本的东西(而且我对更好的方法持开放态度 - 我目前认为就像问题的初始方法而言,就像R程序员一样,而不是C ++程序员。)

(顺便说一句 - 使用arma::vec用于代码的其他部分,我不是为了简单而显示 - 我发现它在这里没用。我讨论过切换它,但是根据我测试过的原则决定反对它部分,它的工作原理,我想做的最后一件事就是引入一个额外的bug ...)

谢谢!

r rcpp
2个回答
2
投票

您可以使用.findName()方法获取相关的index

#include <RcppArmadillo.h>
#include <algorithm>
//[[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;

// [[Rcpp::export]]
IntegerVector fun(const arma::vec& assignment, int k) {

  // count number of peptides per protein
  IntegerVector tab = table(as<IntegerVector>(wrap(assignment)));
  CharacterVector all_proteins = tab.names(); 

  int index = tab.findName(std::string(1, '0' + k));

  tab(index) = 1;
  all_proteins(index) = "-1";
  tab.names() = all_proteins;

  return tab;
}

/*** R
set.seed(23)
x <- rpois(20, 5)
k <- 5

fun(x, k)
*/

输出:

> Rcpp::sourceCpp('table-name.cpp')

> set.seed(23)

> x <- rpois(20, 5)

> k <- 5

> fun(x, k)
 3  4 -1  6  7  9 10 12 
 2  4  1  3  4  2  1  1 

1
投票

你可以编写自己的函数(使用String而不是char):

int first_which_equal(const CharacterVector& x, String y) {

  int n = x.size();
  for (int i = 0; i < n; i++) {
    if (x[i] == y) return(i);
  }

  return -1;
}

此外,似乎tab(kc)正在将kc转换为整数表示。

© www.soinside.com 2019 - 2024. All rights reserved.