On Fri, 2003-10-03 at 17:01, Rajarshi Guha wrote:> Hi, > I'm using a package that has a number of formats. I have C code to > parse these formats the results of which are generally integer arrays. > > I would like to utilize these modules in R rather than writing R code to > read in these files (and also to learn about R extensions).Thanks for the pointers to the above question. I have a few more! 1) I would like my C function to be passed a character string. Thus I define the function as SEXP _loadsets(SEXP filename) { FILE *f; PROTECT(filename = AS_CHARACTER(filename)); f = fopen(filename,"r"); UNPROTECT(1); ..... ..... } However compiling it gives me: loadset.c: In function `_loadsets': loadset.c:25: warning: passing arg 1 of `fopen' from incompatible pointer type gcc -shared -L/usr/local/lib -o loadset.so loadset.o How can I coerce/convert the SEXP type to a char*? 2) The function returns a list object whose elements themselves are lists. Is there any way I can make those elements arrays rather than lists? I see in Rinternals.h there is a function defined as Rf_allocArray(SEXPTYPE, SEXP); What do I need to supply for the second argument? Could I use this function rather than allocVector() to create an actual array object? And then say set elements with INTEGER(anarray)[0] = 1 or are the 'getter'/'setter' functions for arrays different ( I could'nt seem to find any) ? 3) I'm a little puzzled since I allocate a list (say length = 2) object by alist = allocVector(VECSXP,2); and use the same syntax for a vector object. From what I understand a vector is the same as a list. Is this true? 4) When writing C code does it make sense to differentiate between a list object and an array object? Or is it better to simply coerce the returned list objects (via as.array()) from within R. ------------------------------------------------------------------- Rajarshi Guha <rxg218 at psu.edu> <http://jijo.cjb.net> GPG Fingerprint: 0CCA 8EE2 2EEB 25E2 AB04 06F7 1BB9 E634 9B87 56EE ------------------------------------------------------------------- There is no truth to the allegation that statisticians are mean. They are just your standard normal deviates.
On Fri, 4 Oct 2003, Rajarshi Guha wrote:> On Fri, 2003-10-03 at 17:01, Rajarshi Guha wrote: > > Hi, > > I'm using a package that has a number of formats. I have C code to > > parse these formats the results of which are generally integer arrays. > > > > I would like to utilize these modules in R rather than writing R code to > > read in these files (and also to learn about R extensions). > > Thanks for the pointers to the above question. I have a few more! > > 1) I would like my C function to be passed a character string. Thus I > define the function as > > SEXP _loadsets(SEXP filename) > { > FILE *f; > > PROTECT(filename = AS_CHARACTER(filename)); > f = fopen(filename,"r"); > UNPROTECT(1); > ..... > ..... > } > > However compiling it gives me: > > loadset.c: In function `_loadsets': > loadset.c:25: warning: passing arg 1 of `fopen' from incompatible > pointer type > gcc -shared -L/usr/local/lib -o loadset.so loadset.o > > How can I coerce/convert the SEXP type to a char*?Your code can't possibly be right, because it defined filename as SEXP and passes it to a function that accepts const char *. You want fopen(CHARACTER(STRING_ELT(filename,0)), "r") Since filename is a vector of strings (with one element) you need STRING_ELT to extract one of the strings. Now you have a SEXP and need CHARACTER() to extract a pointer to the actual chars, just as I used INTEGER() to extract a pointer to the actual ints in an integer vector SEXP.> 2) The function returns a list object whose elements themselves are > lists.No. It returns a list whose elements are integer vectors.> Is there any way I can make those elements arrays rather than > lists?It's probably easiest to do this manipulation in R afterwards> > 3) I'm a little puzzled since I allocate a list (say length = 2) object > by > > alist = allocVector(VECSXP,2); > > and use the same syntax for a vector object. From what I understand a > vector is the same as a list. Is this true?No (or yes, but not in the way you mean). A list contains vectors or lists as elements. A vector contains numbers or strings. The first element to allocVector says what sort of thing you are allocating.> 4) When writing C code does it make sense to differentiate between a > list object and an array object? Or is it better to simply coerce the > returned list objects (via as.array()) from within R.It is often but not always sensible to do all the manipulation of complicated attributes in R. I think you mean array(), not as.array(). -thomas Thomas Lumley Assoc. Professor, Biostatistics tlumley at u.washington.edu University of Washington, Seattle
You should look at the code in the "foreign" package, which is largely about reading data into C -thomas Thomas Lumley Assoc. Professor, Biostatistics tlumley at u.washington.edu University of Washington, Seattle
I have been strugling to get character data in and out of c functions using the .Call() interface, but I don't succeed getting them back into R. The example: #include "R.h" #include "Rdefines.h" char *cp = "xxxyyyy"; SEXP do_char(SEXP c) { int i; SEXP s; for (i = 0; i < LENGTH(c); i++) printf("%d:[%s]\n", i, CHARACTER_DATA(STRING_ELT(c,i))); /* CHARACTER_VALUE() does not work here! */ s = NEW_CHARACTER(1); CHARACTER_POINTER(s) = cp; c = NEW_CHARACTER(3); SET_STRING_ELT(c,0, s); SET_STRING_ELT(c,1, s); SET_STRING_ELT(c,2, s); return c; } works only for the first half; but I can't manage to fill the string and return it back. Note that I had to use CHARACTER_DATA instead of CHARACTER, which Thomas Lumley suggested last Saturday. -- Edzer