Convert STRSXP or INTSXP to factor

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Convert STRSXP or INTSXP to factor

MorganMorgan
Hi,

Using the R C PAI, is there a way to convert to convert STRSXP or INTSXP to
factor.

The idea would be to do in C something similar to the "factor" function
(example below):

> letters[1:5]
# [1] "a" "b" "c" "d" "e"

> factor(letters[1:5])
# [1] a b c d e
# Levels: a b c d e

There is the function setAttrib the levels of a SXP however when returned
to R the object is of type character not factor. Ideally what i would like
to return from the C function is the same output as above when the input is
of type character.

Please let me if you need more informations.
Thank you
Best regards
Morgan

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: Convert STRSXP or INTSXP to factor

Gabriel Becker-2
Hi Morgan,

So if the goal  is output  identical to  calling factor, one thing youc an
do is construct  and evaluate a call to the R-level factor function. That
would work and  be guaranteed to meet your  requirement.

The factor function is implemented with R code,  without even any direct
calls down to C code, so there isn't any C level functionality already
there that you could try to hit directly.

If you really really needed to write it using only C (and not hitting the R
evaluator), I suppose you could. You'd need to do the following, I think:


   1. Loop through the values to determine the array of levels vector,
   equivalent to a call to unique(x) at the R level. I don't know if there
   are any public API functions that will do this for you, a quick grep
   through the header files  suggests there are not.
   2. Allocate the ouptut INTSXP and determine the underlying integer value
   for each factor element.  Equivalent to a match(x,  levels) in R (x has
   already been converted to character at this point in the R function).
   Getting this to be performant would probably be annoying but is doable
   (e.g., via a hash table or some such)
   3. Do classgets on the the output vector to make it a factor (this will
   set the object bit so you don't need to do that separate)
   4. do setAttrib on the output vector to set the levels attribute (which
   now needs to be  a STRSXP  rather than, e.g., an array of  const char*)
   5. Return the output vector

Personally, unless there was a really compelling reason not to, I'd just do
the  create and evaluate an R-level call thing instead.

Best,
~G




On Mon, Jul 15, 2019 at 3:25 AM Morgan Morgan <[hidden email]>
wrote:

> Hi,
>
> Using the R C PAI, is there a way to convert to convert STRSXP or INTSXP to
> factor.
>
> The idea would be to do in C something similar to the "factor" function
> (example below):
>
> > letters[1:5]
> # [1] "a" "b" "c" "d" "e"
>
> > factor(letters[1:5])
> # [1] a b c d e
> # Levels: a b c d e
>
> There is the function setAttrib the levels of a SXP however when returned
> to R the object is of type character not factor. Ideally what i would like
> to return from the C function is the same output as above when the input is
> of type character.
>
> Please let me if you need more informations.
> Thank you
> Best regards
> Morgan
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: Convert STRSXP or INTSXP to factor

Martin Maechler
>>>>> Gabriel Becker
>>>>>     on Mon, 15 Jul 2019 13:29:28 -0700 writes:

    > Hi Morgan,
    > So if the goal  is output  identical to  calling factor, one thing youc an
    > do is construct  and evaluate a call to the R-level factor function. That
    > would work and  be guaranteed to meet your  requirement.

    > The factor function is implemented with R code,  without even any direct
    > calls down to C code, so there isn't any C level functionality already
    > there that you could try to hit directly.

    > If you really really needed to write it using only C (and not hitting the R
    > evaluator), I suppose you could. You'd need to do the following, I think:

        [... hoop jumping  ...]
        [... hoop jumping  ...]


    > Personally, unless there was a really compelling reason not to, I'd just do
    > the  create and evaluate an R-level call thing instead.

I'm strongly supporting that.  That's the only will not to have
to change your (potentially brittle) C code if  factor() or
as.factor() .. is tweaked in a future version of R.





    > On Mon, Jul 15, 2019 at 3:25 AM Morgan Morgan <[hidden email]>
    > wrote:

    >> Hi,
    >>
    >> Using the R C PAI, is there a way to convert to convert STRSXP or INTSXP to
    >> factor.
    >>
    >> The idea would be to do in C something similar to the "factor" function
    >> (example below):
    >>
    >> > letters[1:5]
    >> # [1] "a" "b" "c" "d" "e"
    >>
    >> > factor(letters[1:5])
    >> # [1] a b c d e
    >> # Levels: a b c d e
    >>
    >> There is the function setAttrib the levels of a SXP however when returned
    >> to R the object is of type character not factor. Ideally what i would like
    >> to return from the C function is the same output as above when the input is
    >> of type character.
    >>
    >> Please let me if you need more informations.
    >> Thank you
    >> Best regards
    >> Morgan
    >>
    >> [[alternative HTML version deleted]]
    >>
    >> ______________________________________________
    >> [hidden email] mailing list
    >> https://stat.ethz.ch/mailman/listinfo/r-devel
    >>

    > [[alternative HTML version deleted]]

    > ______________________________________________
    > [hidden email] mailing list
    > https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel