2015-12-12 4 views
1

я следующий код:mkChar не ускользает знак процента

#include <Rinternals.h> 
#include <cmath> 

extern "C" { 
SEXP myChar(int x) { 
    /*PrintValue(nam);*/ 
    SEXP colnames, result; 
    PROTECT(colnames = Rf_allocVector(STRSXP,2)); 
    char buffer[20]; 
    int n = sprintf(buffer,"%4.2f%%",2.5); 
    SET_STRING_ELT(colnames,0,mkChar(buffer)); 
    n = sprintf(buffer,"%4.2f%c",5.0,0x25); 
    SET_STRING_ELT(colnames,1,mkChar(buffer)); 

    PROTECT(result = Rf_allocVector(VECSXP, 2)); 
    SEXP scol1 = PROTECT(allocVector(REALSXP,10)); 
    SEXP scol2 = PROTECT(allocVector(REALSXP,10)); 

    for (size_t k=0;k<10;++k){ 
     REAL(scol1)[k] = std::pow(k,0.5); 
     REAL(scol2)[k] = std::pow(k,0.7); 
    } 
    SET_VECTOR_ELT(result,0,scol1); 
    SET_VECTOR_ELT(result,1,scol2); 

    setAttrib(result, R_NamesSymbol, colnames); 
    UNPROTECT(4); 
    return(result); 
} 
} 

компилировать так:

R CMD SHLIB myChar.cpp 

И запустить следующее в моей R сессии:

> dyn.load("myChar.so") 
> out<-as.data.frame(.Call("myChar")) 
> out 
     X2.50.  X5.00. 
1 0.000000 0.000000 
2 1.000000 1.000000 
3 1.414214 1.624505 
4 1.732051 2.157669 
5 2.000000 2.639016 
6 2.236068 3.085169 
7 2.449490 3.505144 
8 2.645751 3.904529 
9 2.828427 4.287094 
10 3.000000 4.655537 

Мой вопрос: почему имена столбцов не показывают знак процента? Я использую «%%», чтобы избежать знака процента, но в именах столбцов он преобразуется в период, т. Е. Вместо «X2.50%» я получаю «X2.50». Это особенность mkChar? Есть ли другой способ преобразования массива символов в SEXP?

ответ

4

Нет ничего плохого в коде C/C++. Проблема возникает при принуждении к data.frame. Попробуйте это:

out<-.Call("myChar") 
#names are correct 
names(out) 
#[1] "2.50%" "5.00%" 
#now correctly to data.frame, see ?data.frame 
out<-data.frame(out,check.names=FALSE) 
#  2.50% 5.00% 
#1 0.000000 0.000000 
#2 1.000000 1.000000 
#3 1.414214 1.624505 
#4 1.732051 2.157669 
#5 2.000000 2.639016 
#6 2.236068 3.085169 
#7 2.449490 3.505144 
#8 2.645751 3.904529 
#9 2.828427 4.287094 
#10 3.000000 4.655537 

См check.names аргумент data.frame, чтобы получить понимание того, что происходит.

+1

Имена столбцов Yep --- data.frame часто используются в последующих выражениях (например, обозначения формул), поэтому по умолчанию вызывается 'make.names()', который будет подавлять '%', escape-листы и многое другое. –

0

Чтобы представить символ процента, вы можете использовать \045.

+0

Спасибо за предложение, но не повезло – hadron

+0

Попробуйте ускользнуть через '\%', хотя, я думаю, вы уже это пробовали. Кроме этого, извините, у меня слишком много вариантов. – Aniruth