Примечание: повсюду я буду ссылаться на f
, а не c
.Неправильно называть переменные тем же именем, что и встроенная функция или константа, например c
, T
или F
.Поэтому я изменяю начало вашего кода следующим образом:
library(Rcpp)
f <- factor(c("E", "H", "E", "12", "10", "60", "80", "11", "H", "H"))
Помимо просмотра class(f)
и storage.mode(f)
, полезно взглянуть на str(f)
:
str(f)
# Factor w/ 7 levels "10","11","12",..: 6 7 6 3 1 4 5 2 7 7
По правде говоря, фактор - это целочисленный вектор с «уровнями»: символьный вектор, соответствующий каждому уникальному целочисленному значению.К счастью, вы можете получить это из C ++, используя .attr()
функцию-член Rcpp::IntegerVector
:
cppFunction('CharacterVector fun(IntegerVector x){
// creates an empty character vector the size/length of x.
CharacterVector y = x.size() ;
// Get the levels of x
CharacterVector levs = x.attr("levels");
int n = x.size() - 1 ;
//loop
for(int i = 0; i <= n; i = i + 1){
if(levs[x[i]-1] == "H"){
y[i] = "Home" ;
}else if(levs[x[i]-1] == "E"){
y[i] = "Elsewhere" ;
}else{
y[i] = "Number" ;
} ;
}
return y ;
}')
fun(f)
# [1] "Elsewhere" "Home" "Elsewhere" "Number" "Number" "Number"
# [7] "Number" "Number" "Home" "Home"
Итак, чтобы получить то, что вы хотите, вам пришлось сделать три вещи:
- Измените тип возвращаемого значения с
IntegerVector
на CharacterVector
(хотя вы были совершенно правы, что ввод должен быть IntegerVector
) - Получите уровни коэффициента, используя
CharacterVector levs = x.attr("levels");
- Сравните
levs[x[i]-1]
с "H"
и т. Д., А не x[i]
- x[i]
всегда будет целым числом, давая элемент вектора уровней, которому он соответствует.Мы делаем -1
, поскольку C ++ индексируется 0, а R индексируется 1.
Другие примечания:
Как вы говорите, ясно, что "[вы] пытаюсь научиться использовать Rcpp () в R. "Вам определенно захочется потратить некоторое время на такие ресурсы, как Rcpp для всех (это глава о факторах), Rcpp Gallery (эта конкретная ссылка - статья о факторах), Глава Хэдли о Rcpp , и определенно виньетки Rcpp, доступные здесь .