Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I convert an R character vector to a C character pointer?

Tags:

c

r

I'm trying to pass a character vector from R to C and reference it through a C character pointer. However, I don't know which type conversion macro to use. Below is a small test illustrating my problem.

File test.c:

#include <Rinternals.h>

SEXP test(SEXP chars)
{
   char *s;

   s = CHAR(chars);
   return R_NilValue;
}

File test.R:

dyn.load("test.so")

chars <- c("A", "B")

.Call("test", chars)

Output from R:

> source("test.R")
Error in eval(expr, envir, enclos) : 
  CHAR() can only be applied to a 'CHARSXP', not a 'character'

Any clues?

like image 866
August Karlstrom Avatar asked Feb 19 '13 16:02

August Karlstrom


People also ask

How do I change character vector in R?

R – Convert Character Vector into Integer Vector To convert a given character vector into integer vector in R, call as. integer() function and pass the character vector as argument to this function. as. integer() returns a new vector with the character values transformed into integer values.

How do I convert a character vector to a date vector in R?

You can use the as. Date( ) function to convert character data to dates. The format is as. Date(x, "format"), where x is the character data and format gives the appropriate format.

What is an R character vector?

Character Vector in R is a vector of a type character that is used to store strings and NA values. In this article, I will explain what is a character vector, how to use it with methods like character() , as. character() and is. character() functions.

How do I convert a character vector to numeric in R?

To convert a character vector to a numeric vector, use as. numeric(). It is important to do this before using the vector in any statistical functions, since the default behavior in R is to convert character vectors to factors.


2 Answers

The string in chars can be retrieved by getting each character through the pointer CHAR(STRING_ELT(chars, i)), where 0 <= i < length(chars), and storing it in s[i].

#include <stdlib.h>
#include <Rinternals.h>

SEXP test(SEXP chars)
{
   int n, i;
   char *s;

   n = length(chars);
   s = malloc(n + 1);
   if (s != NULL) {
      for (i = 0; i < n; i++) {
         s[i] = *CHAR(STRING_ELT(chars, i));
      }
      s[n] = '\0';
   } else {
      /*handle malloc failure*/
   }
   return R_NilValue;
}
like image 50
August Karlstrom Avatar answered Sep 28 '22 06:09

August Karlstrom


Character vectors are STRSXP. Each individual element is CHARSXP, so you need something like (untested):

const char *s;
s = CHAR(STRING_ELT(chars, 0));

See the Handling Character Data section of Writing R Extensions. Dirk will be along shortly to tell you how this all will be easier if you just use C++ and Rcpp. :)

like image 21
Joshua Ulrich Avatar answered Sep 28 '22 06:09

Joshua Ulrich