Skip to content

[Rcpp-devel] Help on compilation of Rcpp and RInside

18 messages · Dirk Eddelbuettel, deqiang sun, Romain Francois

#
Hi all,

Could someone help me on compilation of the RInside/inst/examples/standard/rinside_sample0.cpp. This example is the project Rinside0 created by eclipse.

And here is the error message for build.

**** Build of configuration Debug for project Rinside0 ****
make all 
Building file: ../src/Rinside0.cpp
Invoking: GCC C++ Compiler
g++ -I/home/deqiangs/workspace/RInside -I/home/deqiangs/workspace/Rcpp -I/home/deqiangs/workspace/RInside/inst/include -I/home/deqiangs/workspace/Rcpp/inst/include -I/usr/local/lib64/R/include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Rinside0.d" -MT"src/Rinside0.d" -o"src/Rinside0.o" "../src/Rinside0.cpp"
Finished building: ../src/Rinside0.cpp

Building target: Rinside0
Invoking: GCC C++ Linker
g++  -o"Rinside0"  ./src/Rinside0.o   
./src/Rinside0.o: In function `main':
~/workspace/Rinside0/Debug/../src/Rinside0.cpp:17: undefined reference to `RInside::RInside(int, char const* const*, bool)'
~/workspace/Rinside0/Debug/../src/Rinside0.cpp:19: undefined reference to `RInside::operator[](std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
~/workspace/Rinside0/Debug/../src/Rinside0.cpp:21: undefined reference to `RInside::parseEvalQ(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
~/workspace/Rinside0/Debug/../src/Rinside0.cpp:23: undefined reference to `RInside::~RInside()'
./src/Rinside0.o: In function `Rcpp::wrap(char const*)':
~/workspace/Rcpp/inst/include/Rcpp/internal/wrap.h:781: undefined reference to `Rf_mkString'
./src/Rinside0.o: In function `bool Rcpp::Environment::assign<char [15]>(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const (&) [15]) const':
~/workspace/Rcpp/inst/include/Rcpp/Environment.h:270: undefined reference to `Rcpp::Environment::assign(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, SEXPREC*) const'
./src/Rinside0.o:(.gcc_except_table+0x10): undefined reference to `typeinfo for Rcpp::binding_is_locked'
collect2: ld returned 1 exit status
make: *** [Rinside0] Error 1

How should I setup the environment so that the compiler/linker work seamlessly? I can not find any documentation on this.

Best regards,

Dsun
#
(Please don't post twice.)
On 7 April 2011 at 05:20, deqiang sun wrote:
| Hi all,
| 
| Could someone help me on compilation of the RInside/inst/examples/standard/rinside_sample0.cpp. This example is the project Rinside0 created by eclipse.
| 
| And here is the error message for build.
| 
| **** Build of configuration Debug for project Rinside0 ****
| make all 
| Building file: ../src/Rinside0.cpp
| Invoking: GCC C++ Compiler
| g++ -I/home/deqiangs/workspace/RInside -I/home/deqiangs/workspace/Rcpp -I/home/deqiangs/workspace/RInside/inst/include -I/home/deqiangs/workspace/Rcpp/inst/include -I/usr/local/lib64/R/include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Rinside0.d" -MT"src/Rinside0.d" -o"src/Rinside0.o" "../src/Rinside0.cpp"
| Finished building: ../src/Rinside0.cpp
| 
| Building target: Rinside0
| Invoking: GCC C++ Linker
| g++  -o"Rinside0"  ./src/Rinside0.o   

No linking!

| ./src/Rinside0.o: In function `main':
| ~/workspace/Rinside0/Debug/../src/Rinside0.cpp:17: undefined reference to `RInside::RInside(int, char const* const*, bool)'
| ~/workspace/Rinside0/Debug/../src/Rinside0.cpp:19: undefined reference to `RInside::operator[](std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
| ~/workspace/Rinside0/Debug/../src/Rinside0.cpp:21: undefined reference to `RInside::parseEvalQ(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
| ~/workspace/Rinside0/Debug/../src/Rinside0.cpp:23: undefined reference to `RInside::~RInside()'
| ./src/Rinside0.o: In function `Rcpp::wrap(char const*)':
| ~/workspace/Rcpp/inst/include/Rcpp/internal/wrap.h:781: undefined reference to `Rf_mkString'
| ./src/Rinside0.o: In function `bool Rcpp::Environment::assign<char [15]>(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const (&) [15]) const':
| ~/workspace/Rcpp/inst/include/Rcpp/Environment.h:270: undefined reference to `Rcpp::Environment::assign(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, SEXPREC*) const'
| ./src/Rinside0.o:(.gcc_except_table+0x10): undefined reference to `typeinfo for Rcpp::binding_is_locked'
| collect2: ld returned 1 exit status
| make: *** [Rinside0] Error 1

This is obviously an issue with the linker so you have to find out how you
tell Eclipse to tell gcc (and hence ld) about the libraries.
 
| How should I setup the environment so that the compiler/linker work seamlessly? I can not find any documentation on this.

It all works -- using the supplied Makefile. You chose not to use it, you
need to 'port' it to your preferred build tool.

The relevant lines are

LDLIBS := 		$(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS)

as well as all the lines filling the variables uses here.  When I build first
example, it ends up being (and note that paths etc depend on local
installations)

edd at max:~/svn/rinside/pkg/inst/examples/standard$ make rinside_sample0
g++ -I/usr/share/R/include -I/usr/local/lib/R/site-library/Rcpp/include -I"/usr/local/lib/R/site-library/RInside/include" -O3 -pipe -g -Wall    rinside_sample0.cpp  -L/usr/lib64/R/lib -lR  -lblas -llapack -L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp -Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib -L/usr/local/lib/R/site-library/RInside/lib -lRInside -Wl,-rpath,/usr/local/lib/R/site-library/RInside/lib -o rinside_sample0
edd at max:~/svn/rinside/pkg/inst/examples/standard$ 

You could always use make if the Eclipse build tool cannot be tamed...

Dirk
#
Hi Dirk,
Thanks for your help.
I did not see that there's a Makefile in the example folder:) I felt like an idiot. 
I just put Makefile under Eclipse source folder and it compiles/links. All tests passed, though I have to remove older version of R and install the required newer version of R to avoid the embeded R interpreter error.
By the way, I posted twice because I did not receive the email I sent and thought it is failed to mail out. Of couse, I then found out I was on the digest mode.
Best regards,
Deqiang Sun
On Apr 7, 2011, at 6:55 AM, Dirk Eddelbuettel wrote:

            
#
Hi Deqiang,
On 7 April 2011 at 17:55, deqiang sun wrote:
| Hi Dirk,
| Thanks for your help.

My pleasure.

| I did not see that there's a Makefile in the example folder:) I felt like an idiot. 

Stuff happens, there are now a number of files in there.

| I just put Makefile under Eclipse source folder and it compiles/links. All tests passed, though I have to remove older version of R and install the required newer version of R to avoid the embeded R interpreter error.

I do not know what error you refer to but I trust you that it works if you
say it does.

Cheers, Dirk

| By the way, I posted twice because I did not receive the email I sent and thought it is failed to mail out. Of couse, I then found out I was on the digest mode.
| Best regards,
| Deqiang Sun
|
| On Apr 7, 2011, at 6:55 AM, Dirk Eddelbuettel wrote:
| 
| > 
| > (Please don't post twice.)
| >
| > On 7 April 2011 at 05:20, deqiang sun wrote:
| > | Hi all,
| > | 
| > | Could someone help me on compilation of the RInside/inst/examples/standard/rinside_sample0.cpp. This example is the project Rinside0 created by eclipse.
| > | 
| > | And here is the error message for build.
| > | 
| > | **** Build of configuration Debug for project Rinside0 ****
| > | make all 
| > | Building file: ../src/Rinside0.cpp
| > | Invoking: GCC C++ Compiler
| > | g++ -I/home/deqiangs/workspace/RInside -I/home/deqiangs/workspace/Rcpp -I/home/deqiangs/workspace/RInside/inst/include -I/home/deqiangs/workspace/Rcpp/inst/include -I/usr/local/lib64/R/include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/Rinside0.d" -MT"src/Rinside0.d" -o"src/Rinside0.o" "../src/Rinside0.cpp"
| > | Finished building: ../src/Rinside0.cpp
| > | 
| > | Building target: Rinside0
| > | Invoking: GCC C++ Linker
| > | g++  -o"Rinside0"  ./src/Rinside0.o   
| > 
| > No linking!
| > 
| > | ./src/Rinside0.o: In function `main':
| > | ~/workspace/Rinside0/Debug/../src/Rinside0.cpp:17: undefined reference to `RInside::RInside(int, char const* const*, bool)'
| > | ~/workspace/Rinside0/Debug/../src/Rinside0.cpp:19: undefined reference to `RInside::operator[](std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
| > | ~/workspace/Rinside0/Debug/../src/Rinside0.cpp:21: undefined reference to `RInside::parseEvalQ(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
| > | ~/workspace/Rinside0/Debug/../src/Rinside0.cpp:23: undefined reference to `RInside::~RInside()'
| > | ./src/Rinside0.o: In function `Rcpp::wrap(char const*)':
| > | ~/workspace/Rcpp/inst/include/Rcpp/internal/wrap.h:781: undefined reference to `Rf_mkString'
| > | ./src/Rinside0.o: In function `bool Rcpp::Environment::assign<char [15]>(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const (&) [15]) const':
| > | ~/workspace/Rcpp/inst/include/Rcpp/Environment.h:270: undefined reference to `Rcpp::Environment::assign(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, SEXPREC*) const'
| > | ./src/Rinside0.o:(.gcc_except_table+0x10): undefined reference to `typeinfo for Rcpp::binding_is_locked'
| > | collect2: ld returned 1 exit status
| > | make: *** [Rinside0] Error 1
| > 
| > This is obviously an issue with the linker so you have to find out how you
| > tell Eclipse to tell gcc (and hence ld) about the libraries.
| > 
| > | How should I setup the environment so that the compiler/linker work seamlessly? I can not find any documentation on this.
| > 
| > It all works -- using the supplied Makefile. You chose not to use it, you
| > need to 'port' it to your preferred build tool.
| > 
| > The relevant lines are
| > 
| > LDLIBS := 		$(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS)
| > 
| > as well as all the lines filling the variables uses here.  When I build first
| > example, it ends up being (and note that paths etc depend on local
| > installations)
| > 
| > edd at max:~/svn/rinside/pkg/inst/examples/standard$ make rinside_sample0
| > g++ -I/usr/share/R/include -I/usr/local/lib/R/site-library/Rcpp/include -I"/usr/local/lib/R/site-library/RInside/include" -O3 -pipe -g -Wall    rinside_sample0.cpp  -L/usr/lib64/R/lib -lR  -lblas -llapack -L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp -Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib -L/usr/local/lib/R/site-library/RInside/lib -lRInside -Wl,-rpath,/usr/local/lib/R/site-library/RInside/lib -o rinside_sample0
| > edd at max:~/svn/rinside/pkg/inst/examples/standard$ 
| > 
| > You could always use make if the Eclipse build tool cannot be tamed...
| > 
| > Dirk
| > 
| > -- 
| > Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
|
#
Hi all,

Suppose I want to read a csv file including TEXT and NUMBER fields in R by function read.table. 
Is there a way to use the result in C++? Like the way I use in R, say, 2nd column is x[,2], 3rd row is x[3,].
I have gone through the examples in RInside and did not find anything helpful.

PS: Usually when I read a csv into C++ I would do splitting myself line by line and if I want to do operations between columns I need to write addition data structures. 

Thanks,
Dsun
#
On 8 April 2011 at 00:27, deqiang sun wrote:
| Hi all,
| 
| Suppose I want to read a csv file including TEXT and NUMBER fields in R by function read.table. 
| Is there a way to use the result in C++? Like the way I use in R, say, 2nd column is x[,2], 3rd row is x[3,].
| I have gone through the examples in RInside and did not find anything helpful.

You will want to look at _Rcpp_ not RInside for these things.  

It is also a good idea to check the mailing list archive. Here I quickly
search Google for "gmane rcpp-devel Rcpp::DataFrame" and found e.g.

http://article.gmane.org/gmane.comp.lang.r.rcpp/1205 
     -- returning a data.frame from R to C++

and a bunch more. 

But I think you can't pass an entire dataframe from R to C++ _as a single
object_ but it is easy to pass each column.  Have a look at the documentation
and the mailing list archives.

Dirk

| PS: Usually when I read a csv into C++ I would do splitting myself line by line and if I want to do operations between columns I need to write addition data structures. 
| 
| Thanks,
| Dsun
| 
| 
| 
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
#
On 8 April 2011 at 07:20, Dirk Eddelbuettel wrote:
|
| On 8 April 2011 at 00:27, deqiang sun wrote:
| | Hi all,
| | 
| | Suppose I want to read a csv file including TEXT and NUMBER fields in R by function read.table. 
| | Is there a way to use the result in C++? Like the way I use in R, say, 2nd column is x[,2], 3rd row is x[3,].
| | I have gone through the examples in RInside and did not find anything helpful.
| 
| You will want to look at _Rcpp_ not RInside for these things.  
| 
| It is also a good idea to check the mailing list archive. Here I quickly
| search Google for "gmane rcpp-devel Rcpp::DataFrame" and found e.g.
| 
| http://article.gmane.org/gmane.comp.lang.r.rcpp/1205 
|      -- returning a data.frame from R to C++
| 
| and a bunch more. 
| 
| But I think you can't pass an entire dataframe from R to C++ _as a single

Actually, you can as a DataFrame is really just a list.   

Here is a complete example of passing a data.frame in, accessing each column
and returning.  Notice, though, how both the original data gets modified for
int and char (but not date).  That was discussed here at length too; we pass
pointers which is why the change propagates.  Notice also how I effectively
split the data.frame back up into its columns -- by name.

Dirk

edd at max:/tmp$ cat deqiang.R 

library(inline)

D <- data.frame(a=1:3, b=LETTERS[1:3], c=Sys.Date()+0:2, stringsAsFactors=FALSE)
print(D)

src <- '
  Rcpp::DataFrame DL = Rcpp::DataFrame(x);
  Rcpp::IntegerVector a = DL["a"];
  Rcpp::CharacterVector b = DL["b"];
  Rcpp::DateVector c = DL["c"];

  // do something, et
  a[2] = 42;
  b[1] = "foo";
  c[0] = c[0] + 7;                      // move up a week

  return(Rcpp::List::create(Rcpp::Named("DataFrame")=DL,
                            Rcpp::Named("IntVec")=a,
                            Rcpp::Named("CharVec")=b,
                            Rcpp::Named("DateVec")=c));
'

fun <- cxxfunction(signature(x="misc"), body=src, plugin="Rcpp")
print(fun(D))
edd at max:/tmp$ r deqiang.R 
Loading required package: methods
  a b          c
1 1 A 2011-04-08
2 2 B 2011-04-09
3 3 C 2011-04-10
$DataFrame
   a   b          c
1  1   A 2011-04-08
2  2 foo 2011-04-09
3 42   C 2011-04-10

$IntVec
[1]  1  2 42

$CharVec
[1] "A"   "foo" "C"  

$DateVec
[1] "2011-04-15" "2011-04-09" "2011-04-10"

edd at max:/tmp$
#
Ok, I now committed a slightly nice example to RcppExamples, a package I
should revamp to contain more examples.  In there, we now receive a
data.frame, operate on each column, create a new data and return old and new.

The core of the code (inside the try/catch protection) is

      // construct the data.frame object
      Rcpp::DataFrame DF = Rcpp::DataFrame(Dsexp);

      // and access each column by name
      Rcpp::IntegerVector a = DF["a"];
      Rcpp::CharacterVector b = DF["b"];
      Rcpp::DateVector c = DF["c"];
      
      // do something
      a[2] = 42;
      b[1] = "foo";
      c[0] = c[0] + 7;                      // move up a week

      // create a new data frame
      Rcpp::DataFrame NDF = 
	  Rcpp::DataFrame::create(Rcpp::Named("a")=a,
				  Rcpp::Named("b")=b,
				  Rcpp::Named("c")=c);

      // and return old and new in list
      return(Rcpp::List::create(Rcpp::Named("origDataFrame")=DF,
				Rcpp::Named("newDataFrame")=NDF));


Dirk
3 days later
#
Hi Dirk,

Thanks very much for your example. From this example I learned how to passing data back and forth between R and C++. 
The example is R code and uses piece of C++ code in side R program. 
Well, it's better if you put this example(by only making slight changes to make R embeded in C++) inside package RInside.

Accessing data by column name is the feature I ( and other people) usually want. 
However, is there a way to access the data Frame by row number?

Regards.

Dsun
On Apr 8, 2011, at 9:56 AM, Dirk Eddelbuettel wrote:

            
#
Le 12/04/11 10:57, deqiang sun a ?crit :
No. You access the column, and then do whatever with each element, as in 
Dirk's example.

  
    
#
I agree I realized the row is usually mixed of numbers and texts.
On Apr 12, 2011, at 4:14 AM, Romain Francois wrote:

            
#
How should I read the txt in the following context?
c3	3a
c1	1b
c2	2c

The code I have is 
		RInside R(argc, argv);
		SEXP ans;

		std::string txt = "a=read.csv('xxx.xls',sep='\t',head=F)";
		ans = R.parseEval(txt);
		Rcpp::DataFrame DF(ans);

		Rcpp::StringVector x1 = DF["V1"];
		Rcpp::StringVector x2 = DF["V2"];

But the print of x1 and x2 is 
3	3	
1	1	
2	2	

What's wrong with my code?

Thanks,

Dsun
On Apr 12, 2011, at 4:14 AM, Romain Francois wrote:

            
#
Hmmm. I have a bad feeling about this. I sense a disturbance in the force.

It goes down to coerceVector not doing its job on factors:

require( Rcpp )
require( inline )
v1 <- as.factor( c("c3", "c1", "c2" ) )
fx <- cfunction( signature( x = "factor" ), '
     SEXP s = PROTECT( coerceVector( x, STRSXP ) ) ;
     UNPROTECT(1);
     return s ;
' )


 > fx( as.integer( v1 ) )
[1] <NA> <NA> <NA>
Levels: c1 c2 c3

 > version
                _
platform       x86_64-apple-darwin9.8.0
arch           x86_64
os             darwin9.8.0
system         x86_64, darwin9.8.0
status         beta
major          2
minor          13.0
year           2011
month          04
day            04
svn rev        55296
language       R
version.string R version 2.13.0 beta (2011-04-04 r55296)

coerceVector is used by r_cast<STRSXP>, which is used by the ctor for 
StringVector.

...

Le 12/04/11 12:38, deqiang sun a ?crit :

  
    
#
Le 12/04/11 13:30, Romain Francois a ?crit :
Sorry, I meant fx( v1 )
>

  
    
#
On 12 April 2011 at 05:38, deqiang sun wrote:
| How should I read the txt in the following context?
| c3	3a
| c1	1b
| c2	2c
| 
| The code I have is 
| 		RInside R(argc, argv);
| 		SEXP ans;
| 
| 		std::string txt = "a=read.csv('xxx.xls',sep='\t',head=F)";
| 		ans = R.parseEval(txt);
| 		Rcpp::DataFrame DF(ans);
| 
| 		Rcpp::StringVector x1 = DF["V1"];
| 		Rcpp::StringVector x2 = DF["V2"];
| 
| But the print of x1 and x2 is 
| 3	3	
| 1	1	
| 2	2	
| 
| What's wrong with my code?

The read.csv() function and its cousins default to stringsAsFactors=TRUE. 

So the '3 1 2' are the factor levels. You want either 

    std::string txt = "a=read.csv('xxx.xls',sep='\t',"
                      "head=FALSE,stringsAsFactors=FALSE)";

or set it as a global option.  Google for stringsAsFactors, this is
documented and are ways around it.  

Dirk

PS  I personally would also set column names in the data file or R code.

 
| Thanks,
| 
| Dsun
| On Apr 12, 2011, at 4:14 AM, Romain Francois wrote:
| 
| > Le 12/04/11 10:57, deqiang sun a ?crit :
| >> Hi Dirk,
| >> 
| >> Thanks very much for your example. From this example I learned how to passing data back and forth between R and C++.
| >> The example is R code and uses piece of C++ code in side R program.
| >> Well, it's better if you put this example(by only making slight changes to make R embeded in C++) inside package RInside.
| >> 
| >> Accessing data by column name is the feature I ( and other people) usually want.
| >> However, is there a way to access the data Frame by row number?
| > 
| > No. You access the column, and then do whatever with each element, as in 
| > Dirk's example.
| > 
| >> Regards.
| >> 
| >> Dsun
| >> On Apr 8, 2011, at 9:56 AM, Dirk Eddelbuettel wrote:
| >> 
| >>> 
| >>> Ok, I now committed a slightly nice example to RcppExamples, a package I
| >>> should revamp to contain more examples.  In there, we now receive a
| >>> data.frame, operate on each column, create a new data and return old and new.
| >>> 
| >>> The core of the code (inside the try/catch protection) is
| >>> 
| >>>      // construct the data.frame object
| >>>      Rcpp::DataFrame DF = Rcpp::DataFrame(Dsexp);
| >>> 
| >>>      // and access each column by name
| >>>      Rcpp::IntegerVector a = DF["a"];
| >>>      Rcpp::CharacterVector b = DF["b"];
| >>>      Rcpp::DateVector c = DF["c"];
| >>> 
| >>>      // do something
| >>>      a[2] = 42;
| >>>      b[1] = "foo";
| >>>      c[0] = c[0] + 7;                      // move up a week
| >>> 
| >>>      // create a new data frame
| >>>      Rcpp::DataFrame NDF =
| >>> 	  Rcpp::DataFrame::create(Rcpp::Named("a")=a,
| >>> 				  Rcpp::Named("b")=b,
| >>> 				  Rcpp::Named("c")=c);
| >>> 
| >>>      // and return old and new in list
| >>>      return(Rcpp::List::create(Rcpp::Named("origDataFrame")=DF,
| >>> 				Rcpp::Named("newDataFrame")=NDF));
| >>> 
| >>> 
| >>> Dirk
| >>> --
| >>> Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
| > 
| > -- 
| > Romain Francois
| > Professional R Enthusiast
| > +33(0) 6 28 91 30 30
| > http://romainfrancois.blog.free.fr
| > http://romain-francois.com
| > |- http://bit.ly/fhqbRC : Rcpp workshop in Chicago on April 28th
| > |- http://bit.ly/dFyZGB : Hydraulique au Montpellier Comedie Club
| > `- http://bit.ly/eVXit9 : Eponyme : 40 minutes stand up
| > 
| > 
|
#
Should work as expected with the next version of Rcpp (svn version >= 
3000).

require( Rcpp )
require( inline )
df <- data.frame(
     V1 = c("c3", "c1", "c2" ),
     V2 = c("3a", "1b", "2c" )
     )
fx <- cxxfunction( signature( x = "data.frame" ), '
     DataFrame DF(x);
     StringVector v1 = DF["V1"];
     StringVector v2 = DF["V2"] ;
     return List::create( v1, v2) ;
' , plugin = "Rcpp" )


 > fx( df )
[[1]]
[1] "c3" "c1" "c2"

[[2]]
[1] "3a" "1b" "2c"

Romain


Le 12/04/11 12:38, deqiang sun a ?crit :

  
    
#
Thanks, the stringsAsFactors=FALSE option works.

Dsun
On Apr 12, 2011, at 6:36 AM, Dirk Eddelbuettel wrote:

            
#
On 12 April 2011 at 15:04, deqiang sun wrote:
| Thanks, the stringsAsFactors=FALSE option works.

And Rcpp 0.9.4 is now on CRAN which contains a fix Romain but that no longer
requires it.

Dirk

 
| Dsun
| On Apr 12, 2011, at 6:36 AM, Dirk Eddelbuettel wrote:
| 
| >
| > On 12 April 2011 at 05:38, deqiang sun wrote:
| > | How should I read the txt in the following context?
| > | c3	3a
| > | c1	1b
| > | c2	2c
| > | 
| > | The code I have is 
| > | 		RInside R(argc, argv);
| > | 		SEXP ans;
| > | 
| > | 		std::string txt = "a=read.csv('xxx.xls',sep='\t',head=F)";
| > | 		ans = R.parseEval(txt);
| > | 		Rcpp::DataFrame DF(ans);
| > | 
| > | 		Rcpp::StringVector x1 = DF["V1"];
| > | 		Rcpp::StringVector x2 = DF["V2"];
| > | 
| > | But the print of x1 and x2 is 
| > | 3	3	
| > | 1	1	
| > | 2	2	
| > | 
| > | What's wrong with my code?
| > 
| > The read.csv() function and its cousins default to stringsAsFactors=TRUE. 
| > 
| > So the '3 1 2' are the factor levels. You want either 
| > 
| >    std::string txt = "a=read.csv('xxx.xls',sep='\t',"
| >                      "head=FALSE,stringsAsFactors=FALSE)";
| > 
| > or set it as a global option.  Google for stringsAsFactors, this is
| > documented and are ways around it.  
| > 
| > Dirk
| > 
| > PS  I personally would also set column names in the data file or R code.
| > 
| > 
| > | Thanks,
| > | 
| > | Dsun
| > | On Apr 12, 2011, at 4:14 AM, Romain Francois wrote:
| > | 
| > | > Le 12/04/11 10:57, deqiang sun a ?crit :
| > | >> Hi Dirk,
| > | >> 
| > | >> Thanks very much for your example. From this example I learned how to passing data back and forth between R and C++.
| > | >> The example is R code and uses piece of C++ code in side R program.
| > | >> Well, it's better if you put this example(by only making slight changes to make R embeded in C++) inside package RInside.
| > | >> 
| > | >> Accessing data by column name is the feature I ( and other people) usually want.
| > | >> However, is there a way to access the data Frame by row number?
| > | > 
| > | > No. You access the column, and then do whatever with each element, as in 
| > | > Dirk's example.
| > | > 
| > | >> Regards.
| > | >> 
| > | >> Dsun
| > | >> On Apr 8, 2011, at 9:56 AM, Dirk Eddelbuettel wrote:
| > | >> 
| > | >>> 
| > | >>> Ok, I now committed a slightly nice example to RcppExamples, a package I
| > | >>> should revamp to contain more examples.  In there, we now receive a
| > | >>> data.frame, operate on each column, create a new data and return old and new.
| > | >>> 
| > | >>> The core of the code (inside the try/catch protection) is
| > | >>> 
| > | >>>      // construct the data.frame object
| > | >>>      Rcpp::DataFrame DF = Rcpp::DataFrame(Dsexp);
| > | >>> 
| > | >>>      // and access each column by name
| > | >>>      Rcpp::IntegerVector a = DF["a"];
| > | >>>      Rcpp::CharacterVector b = DF["b"];
| > | >>>      Rcpp::DateVector c = DF["c"];
| > | >>> 
| > | >>>      // do something
| > | >>>      a[2] = 42;
| > | >>>      b[1] = "foo";
| > | >>>      c[0] = c[0] + 7;                      // move up a week
| > | >>> 
| > | >>>      // create a new data frame
| > | >>>      Rcpp::DataFrame NDF =
| > | >>> 	  Rcpp::DataFrame::create(Rcpp::Named("a")=a,
| > | >>> 				  Rcpp::Named("b")=b,
| > | >>> 				  Rcpp::Named("c")=c);
| > | >>> 
| > | >>>      // and return old and new in list
| > | >>>      return(Rcpp::List::create(Rcpp::Named("origDataFrame")=DF,
| > | >>> 				Rcpp::Named("newDataFrame")=NDF));
| > | >>> 
| > | >>> 
| > | >>> Dirk
| > | >>> --
| > | >>> Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
| > | > 
| > | > -- 
| > | > Romain Francois
| > | > Professional R Enthusiast
| > | > +33(0) 6 28 91 30 30
| > | > http://romainfrancois.blog.free.fr
| > | > http://romain-francois.com
| > | > |- http://bit.ly/fhqbRC : Rcpp workshop in Chicago on April 28th
| > | > |- http://bit.ly/dFyZGB : Hydraulique au Montpellier Comedie Club
| > | > `- http://bit.ly/eVXit9 : Eponyme : 40 minutes stand up
| > | > 
| > | > 
| > | 
| > 
| > -- 
| > Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
|