Извлечение элемента во вложенный список в Rcpp - PullRequest
1 голос
/ 08 февраля 2020

Я пытаюсь извлечь элемент из списка и сделать что-то с его значением, используя R cpp. Но я не могу сделать назначение.

Вот в основном то, чего я хочу достичь с помощью кода R:

mylist = list(steps = list(`1` = list(a = 7, b = "abc"), 
                           `2` = list(a = 3), 
                           `3` = list(a = 5, b = NULL)))
# This is the desired behavior that I can program in R
step_name = "1"
b = ifelse(is.null(mylist$steps[[step_name]][["b"]]), 
           "", mylist$steps[[step_name]][["b"]])
# Do something with the value of b

Следующий код не может сделать присвоение b. Значение a извлекается как следует. Я не знаю, что мне здесь не хватает.

library(Rcpp)
cppFunction('int foo(Rcpp::List x, std::string step_name) {
  Rcpp::List steps = x("steps");
  Rcpp::List step = steps(step_name);
  int a = step("a");
  //// Not declaring b causes "not declared in this scope" error 
  //// so I initialize it with a random value.
  std::string b = "random";
  if (step.containsElementNamed("b")){
    Rcout << "b is in List!" << "\\n";
    if (!Rf_isNull(step("b"))) {
      Rcout << "b is not NULL!" << "\\n";
      if (TYPEOF(step("b")) == STRSXP)
        Rcout << "b is character!" << "\\n";
      std::string b = step("b");
    } else {
      Rcout << "b is NULL!" << "\\n";
      std::string b = "efg";
    }          
  } else {
    Rcout << "b is not in List!" << "\\n";
    std::string b = "xyz";
  }
  Rcout << "The Value of b is " << b << ".\\n";
  if (b == "abc") {
    //// Do something with the value of b
  }       
  return a;
}')

foo(mylist, "1")
## b is in List!
## b is not NULL!
## b is character!
## The Value of b is random.
## [1] 7
foo(mylist, "2")
## b is not in List!
## The Value of b is random.
## [1] 3
foo(mylist, "3")
## b is in List!
## b is NULL!
## The Value of b is random.
## [1] 5

1 Ответ

2 голосов
/ 08 февраля 2020

Похоже, что это в основном проблема с областью видимости и тип переменной. Я считаю, что объявления std::string b в операторах if then являются локальными. Любые изменения там не последние.

Затем ошибки в ваших комментариях пытаются присвоить LHS std::string с RHS Rcpp:Vector. Хотя я уверен, что есть лучшие способы преобразования и / или упрощения, в приведенном ниже решении просто объявляется Rcpp::CharacterVector b.

library(Rcpp)
cppFunction('int foo(Rcpp::List x, std::string step_name) {
  Rcpp::List steps = x("steps");
  Rcpp::List step = steps(step_name);
  int a = step("a");
  //// Not declaring b causes "not declared in this scope" error 
  //// so I initialize it with a random value.
  CharacterVector b; #############
  if (step.containsElementNamed("b")){
    Rcout << "b is in List!" << "\\n";
    if (!Rf_isNull(step("b"))) {
      Rcout << "b is not NULL!" << "\\n";
      if (TYPEOF(step("b")) == STRSXP)
        Rcout << "b is character!" << "\\n";
      b = step("b");
    } else {
      Rcout << "b is NULL!" << "\\n";
    }          
  } else {
    Rcout << "b is not in List!" << "\\n";
  }
  Rcout << "The size of b is " << b.size() << ".\\n"; #########
  if (b.size() > 0 && b[0] == "abc") { ################
    Rcout << "Do something with b.\\n";
    //// Do something with the value of b
  }       
  return a;
}')

mylist = list(steps = list(`1` = list(a = 7, b = "abc"), 
                           `2` = list(a = 3), 
                           `3` = list(a = 5, b = NULL)))

foo(mylist, "1")
# b is in List!
# b is not NULL!
# b is character!
# The size of b is 1.
# Do something with b.
# [1] 7
foo(mylist, "2")
# b is not in List!
# The size of b is 0.
# [1] 3
foo(mylist, "3")
# b is in List!
# b is NULL!
# The size of b is 0.
# [1] 5
...