Have error in trying to use R function in Rcpp for the first time - rcpp

Trying to compile a function in Rcpp that brings in a R package called read_excel.
Not sure what the error means but perhaps it cant find the function in the package?
cppFunction('IntegerVector readYear(CharacterVector filePath ) {
IntegerVector Year(filePath.size());
int n=filePath.size();
Environment pkg = Environment::namespace_env("readxl");
Function read_excel=pkg["read_excel"];
for( int i =0 ; i<n; i++){
Year[i] = read_excel(Named("path") = filePath[i],
_["range"] = "B3:B3",
_["col_names"] = false );
}
return Year;
}')
Error message:
file391220cd2e2.cpp: In function ‘Rcpp::IntegerVector readYear(Rcpp::CharacterVector)’:
file391220cd2e2.cpp:18:22: error: invalid conversion from ‘SEXP {aka SEXPREC*}’ to ‘Rcpp::traits::storage_type<13>::type {aka int}’ [-fpermissive]
Year[i] = read_excel(Named("path") = filePath[i],
^
make: *** [file391220cd2e2.o] Error 1
g++ -std=gnu++11 -I"/opt/R/3.6.0/lib/R/include" -DNDEBUG -I"/home/rstudio-user/R/x86_64-pc-linux-gnu-library/3.6/Rcpp/include" -I"/tmp/RtmpbaxzNs/sourceCpp-x86_64-pc-linux-gnu-1.0.2" -I/usr/local/include -fpic -g -O2 -c file391220cd2e2.cpp -o file391220cd2e2.o
/opt/R/3.6.0/lib/R/etc/Makeconf:176: recipe for target 'file391220cd2e2.o' failed
Error in sourceCpp(code = code, env = env, rebuild = rebuild, cacheDir = cacheDir, :
Error 1 occurred building shared library.

The error message means that it is not directly possible to convert the return type of an R function (SEXP) to the storage type of an IntegerVector (int). You can instruct Rcpp to do so using Rcpp::as<int>(...):
Rcpp::cppFunction('IntegerVector readYear(CharacterVector filePath ) {
int n = filePath.size();
IntegerVector Year(n);
Environment pkg = Environment::namespace_env("readxl");
Function read_excel=pkg["read_excel"];
for(int i =0; i<n; ++i){
Year[i] = Rcpp::as<int>(read_excel(_("path") = filePath[i],
_["range"] = "B3:B3",
_["col_names"] = false ));
}
return Year;
}')
BTW, I hope there is a good reason for doing this in C++, since as it is the function will be slower than the equivalent R function, since calling R functions from C++ has its price.

Related

assign an int(eg. 10) to a string member in a struct in c++, why it compile success?

I'm practicing <thinking in c++ > for chapter5, ex01:
Write a struct called Lib that contains three string objects a, b, and c.
In main( ) create a Lib object called x and assign to x.a, x.b, and x.c.
Print out the values.
in the beginning, I'm trying:
// ex02.cpp
#include <iostream>
#include <string>
using namespace std;
struct Lib {
string a;
string b;
string c;
};
int main(){
Lib x;
x.a = 1; // here I forgot the string object, and incorrectly assign the wrong value to x.a
x.b = 2;
x.c = 3;
cout << x.a << " " << x.b << " " << x.c << endl;
return 0;
}
and it can compile successfully, but the run result seems only two blank spaces:
[root#VM-0-2-centos ch05]# g++ ex02.cpp
[root#VM-0-2-centos ch05]# ./a.out
[root#VM-0-2-centos ch05]#
at this time I find the wrong assignment. but why it should not give a compile error?
when I modify the assignment to the follows:
x.a = "hello";
x.b = "world";
x.c = "welcome";
it compiles success, and give the right run result:
[root#VM-0-2-centos ch05]# g++ ex02.cpp
[root#VM-0-2-centos ch05]# ./a.out
hello world welcome
[root#VM-0-2-centos ch05]#
my question is why x.a = 1 can compile success?
and when I try:
string test = 1;
it will compile error:
error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]
U need to verify my statement by yourself. To see string code.
First, When u declare Lib x, the member of x (a, b, c) will call string constructor. So when assign value to the member of x (x.a = 1), it will call "=operation".
However, string test = 1, it will call constructor.
the most difference is caller. the type of parameter of string constructor is "const char*", but "=operation" can get other type of parameter. So, x.a = 1 at compile is passing.
Note, "int" will cast to a certain type by default.
Thx, #Muqali He, you give me the hint and direction.
I try to understand the string class from here: https://www.cplusplus.com/reference/string/string/operator=/
And I understand a bit more.
for c++98, when I use "=", there is three overload member function:
when I try:
string t2;
t2 = "test";
it's OK. and I try:
string t3;
t3 = 256;
it will get a warning:
warning: overflow in implicit constant conversion
at this time, 256 will be recognized as a char. when you output this value, it will transform into its ASCII code:
string t4;
t4 = 100;
cout << "t4= " << t4 << endl;
the ouput is
t4 = d
if I try:
string t5 = 100; // it will compile error
because there's no corresponding constructor

There's a problem on my code about cs50 in mario problem

enter image description here
Hello, I was coding for cs50 in the mario problem but it seems that there is an error that says:
^
mario.c:20:26: error: use of undeclared identifier 'k'
for (k = 1; k <= n - i; k++){
^
3 errors generated.
<builtin>: recipe for target 'mario' failed
make: *** [mario] Error 1
Why is this so? :/
This is because you haven't declared the variable k anywhere.
Usually, in a for loop, the iterator variable is declared at the start. For example,
for (int i = 0; i < 10; i++)
{
// code to run
}
In your code, you haven't declared 'k' by explicitly stating int k = 0; Hence, to fix your code, try adding an int (to declare the variable k as an int) before the first k.

Caesar problem code generating "error: implicitly declaring library function 'strlen' with type 'unsigned long (const char *)'

I am doing the CS50 course and am on week 2. One of the problems of week 2 is called "Caesar". Essentially you have to write code which cyphers text by shifting letters that use the users inputted preferred number. After running my code I keep getting this error
"error: implicitly declaring library function 'strlen' with
type 'unsigned long (const char *)'
[-Werror,-Wimplicit-function-declaration]
for(i = 0, l = strlen(text); i < n; i++)"
This is the code:
int main(int argc, string argv[])
{
string n = argv[1];
int y = argc;
int key = get_int("./caesar ");//getting the number from the user
int k = (key);//assigning key a variable name.
string text = get_string("plaintext: ");//letting the user input their text.
if (key < 1)//Trying to make limit for acceptable input.
{
printf("ERROR");
return 1;
}
int l;
int i;
//for loop containing the encipher process
for(i = 0, l = strlen(text); i < n; i++)
{
if(isalpha(i))
{
if (isupper[i])
{
printf("ciphertext: %c",(text[i] + k)%26 + 65);
}
else (islower[i])
{
printf("ciphertext: %c",(text[i] + k)%26 + 65);
}
}
}
printf("ciphertext: %c", d || c);
return;
int checking_key(int y,string n)
int num = argc;
string key = y;
int num_key = atoi(key);
if(argc != 2)
{
return 0;
}
else
{
if (num_key > 0)
{
return num_key;
}
else
{
return 0;
}
}
}
From man strlen:
Synopsis
#include <string.h>
size_t strlen(const char *s);
Just like one needs to "include" cs50.h to use any of the get_* functions, string.h must be "include"d to access its functions, eg strlen.
Additionally (per comments):
The "ordered comparison" in the compile error
ordered comparison between pointer and integer ('int' and 'string' (aka 'char *')) [-Werror] for(i = 0, l = strlen(text); i < n; i++)
is i < n. Error says one of them is an int and one of them is a string.
On closer inspection this program is a long way from a clean compile. Recommend you follow along with the spec and "approach this problem one step at a time"

Use standard includes in Rcpp

I installed R along with RStudio and RTools and currently I'm trying to get Rcpp running. I tried this code as an testfile:
#include <RcppArmadillo.h>
#include <cmath.h>
//[[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
// [[Rcpp::export]]
double Mutual_Information(
arma::mat joint_dist
){
joint_dist = joint_dist/sum(sum(joint_dist));
double mutual_information = 0;
int num_rows = joint_dist.n_rows;
int num_cols = joint_dist.n_cols;
arma::mat colsums = sum(joint_dist,0);
arma::mat rowsums = sum(joint_dist,1);
for(int i = 0; i < num_rows; ++i){
for(int j = 0; j < num_cols; ++j){
double temp = log((joint_dist(i,j)/(colsums[j]*rowsums[i])));
if(!std::isfinite(temp)){
temp = 0;
}
mutual_information += joint_dist(i,j) * temp;
}
}
return mutual_information;
}
but I get this error message:
c:/Rtools/mingw_64/bin/g++ -std=gnu++11
-I"C:/PROGRA~1/R/R-34~1.2/include" -DNDEBUG -I../inst/include -fopenmp -I"C:/Users/root/Documents/R/win-library/3.4/Rcpp/include" -I"C:/Users/root/Documents/R/win-library/3.4/RcppArmadillo/include" -I"C:/Users/root/OneDrive/Uni/SEMEST~1/PROJEK~1/test/src" -I"C:/Users/root/OneDrive/Uni/Semester 3/Projektarbeit/test/inst/include"
-I"d:/Compiler/gcc-4.9.3/local330/include" -O2 -Wall -mtune=core2 -c rcpp_hello_world.cpp -o rcpp_hello_world.o rcpp_hello_world.cpp:2:19: fatal error: cmath.h: No such file or
directory #include
^ compilation terminated. make: *** [rcpp_hello_world.o]
Error 1 Warnmeldung: Ausführung von Kommando
'make -f "C:/PROGRA~1/R/R-34~1.2/etc/x64/Makeconf" -f
"C:/PROGRA~1/R/R-34~1.2/share/make/winshlib.mk" CXX='$(CXX11)
$(CXX11STD)' CXXFLAGS='$(CXX11FLAGS)' CXXPICFLAGS='$(CXX11PICFLAGS)'
SHLIB_LDFLAGS='$(SHLIB_CXX11LDFLAGS)' SHLIB_LD='$(SHLIB_CXX11LD)'
SHLIB="sourceCpp_3.dll" WIN=64 TCLBIN=64 OBJECTS="rcpp_hello_world.o"'
ergab Status 2 Error in Rcpp::sourceCpp("src/rcpp_hello_world.cpp") :
Error 1 occurred building shared library. In addition: Warning
message: In normalizePath(path.expand(path), winslash, mustWork) :
path[1]="C:/Users/root/OneDrive/Uni/Semester
3/Projektarbeit/test/src/../inst/include": Das System kann den
angegebenen Pfad nicht finden
library("Rcpp") and library("RcppArmadillo") are loaded successfully ...
So as I understand this error it could not find the include file. The path the compiler is looking for does not exist. It should handle the include path itself I assume ..
Including this header file in QT or Visual Studio works without any errors ..
Do I need to adjust some PATH settings? I'm running this on Windows 10 x64
I can't find any solution using google so I hope you can help me on this.
Thanks a lot
There is no header cmath.h as the error message said. You probably meant cmath.
The repaired and simplified (no namespace declaration needed) file passes:
#include <RcppArmadillo.h>
#include <cmath>
//[[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
double Mutual_Information(arma::mat joint_dist){
joint_dist = joint_dist/sum(sum(joint_dist));
double mutual_information = 0;
int num_rows = joint_dist.n_rows;
int num_cols = joint_dist.n_cols;
arma::mat colsums = sum(joint_dist,0);
arma::mat rowsums = sum(joint_dist,1);
for(int i = 0; i < num_rows; ++i){
for(int j = 0; j < num_cols; ++j){
double temp = log((joint_dist(i,j)/(colsums[j]*rowsums[i])));
if(!std::isfinite(temp)){
temp = 0;
}
mutual_information += joint_dist(i,j) * temp;
}
}
return mutual_information;
}
i.e.
R> sourceCpp("/tmp/soQ.cpp")
R>
no errors here.

Why patching a string using .ptr fails under Linux64 but not under Win32?

Why the small sample below fails under Linux64 but not under Windows32?
module test;
import std.string, std.stdio;
void main(string[] args)
{
string a = "abcd=1234";
auto b = &a;
auto Index = indexOf(*b, '=');
if (Index != -1)
*cast (char*) (b.ptr + Index) = '#';
writeln(*b);
readln;
}
one thing to remember is that string is an alias to (immutable char)[] which means that trying to write to the elements is undefined behavior
one of the reasons that I can think the behavior differs is that under linux64 the compiler puts the string data in write-protected memory, which means that *cast (char*) (b.ptr + Index) = '#'; fails (either silently or with segfault)

Resources