代码之家  ›  专栏  ›  技术社区  ›  dww Jarretinha

Rcpp中字符串与单个值的矢量化比较

  •  0
  • dww Jarretinha  · 技术社区  · 3 年前

    这个 == Rcpp中的运算符在将数字向量与单个值进行比较时按预期工作。即,将向量的每个元素与值进行比较,并返回一个逻辑向量。例如,考虑以下行为符合预期:

    library(Rcpp)
    cppFunction('
    CharacterVector test_vals(NumericVector x) {
      if (is_true(any(x == 3))) return ("Values include 3");
      return ("3 not found");
    }')
    test_vals(1:2)
    # [1] "3 not found"
    test_vals(1:5)
    # [1] "Values include 3"
    

    但是,如果我尝试将字符向量与字符标量进行比较,它似乎只测试向量的第一个元素:

    cppFunction('
    CharacterVector test_names(NumericVector x) {
      CharacterVector y = x.attr("names");
      if (is_true(any(y == CharacterVector::create("foo")))) return ("Names include foo");
      return ("foo not found");
    }')
    test_names(c(a=1, b=2, foo=3))
    # [1] "foo not found"
    test_names(c(foo=3, a=1, b=2))
    # [1] "Names include foo"
    

    我知道比较两个相同长度的字符向量似乎是以向量化的方式工作的,正如预期的那样:

    cppFunction('
    CharacterVector test_names(NumericVector x) {
      CharacterVector y = x.attr("names");
      CharacterVector foo(x.size());
      foo.fill("foo");
      if (is_true(any(y == foo))) return ("Names include foo");
      return ("foo not found");
    }')
    test_names(c(a=1, b=2, foo=3))
    # [1] "Names include foo"
    test_names(c(foo=3, a=1, b=2))
    # [1] "Names include foo"
    test_names(c(a=1, b=2))
    # [1] "foo not found"
    

    这是否意味着字符向量与单个值的比较还没有实现 Rcpp 或者我只是想知道怎么做?

    1 回复  |  直到 3 年前
        1
  •  1
  •   Dirk is no longer here    3 年前

    继我们的快速讨论之后,这里有一个 false .

    代码

    #include <Rcpp.h>
    
    // [[Rcpp::export]]
    bool contains(std::vector<std::string> sv, std::string txt) {
        for (auto s: sv) {
            if (s == txt) return true;
        }
        return false;
    }
    
    /*** R
    sv <- c("a", "b", "c")
    contains(sv, "foo")
    sv[2] <- "foo"
    contains(sv, "foo")
    */
    

    > Rcpp::sourceCpp("~/git/stackoverflow/66895973/answer.cpp")
    
    > sv <- c("a", "b", "c")
    
    > contains(sv, "foo")
    [1] FALSE
    
    > sv[2] <- "foo"
    
    > contains(sv, "foo")
    [1] TRUE
    > 
    

    这实际上只是在寻找我们可能已经拥有的(大约)10万行Rcpp或者STL可能拥有的东西之前从臀部开始拍摄。。。

    同样的方法也适用于前面的命名属性示例,当然,对于 CharacterVector ,和/或使用从它到 std::vector<std::string> 我们以前在这里,或者。。。如果您有一个旧的编译器,请切换 for