2011-07-12 8 views

risposta

15

Un data.frame è una lista, quindi lungo le linee di

#include <Rdefines.h> 

SEXP df_fun(SEXP df) 
{ 
    int i, len = Rf_length(df); 
    SEXP result; 
    PROTECT(result = NEW_CHARACTER(len)); 
    for (i = 0; i < len; ++i) 
     switch(TYPEOF(VECTOR_ELT(df, i))) { 
     case INTSXP: 
      SET_STRING_ELT(result, i, mkChar("integer")); 
      break; 
     case REALSXP: 
      SET_STRING_ELT(result, i, mkChar("numeric")); 
      break; 
     default: 
      SET_STRING_ELT(result, i, mkChar("other")); 
      break; 
     }; 
     UNPROTECT(1); 
    return result; 
} 

e poi, dopo R CMD SHLIB df_fun.c

> dyn.load("df_fun.so") 
> df=data.frame(x=1:5, y=letters[1:5], z=pi, stringsAsFactors=FALSE) 
> .Call("df_fun", df) 
[1] "integer" "other" "numeric" 

Utilizzare GET_CLASS, GET_ATTR e altre macro in Rdefines.h (o le loro funzioni equivalenti, come getAttrib) per scoprire altre informazioni sul frame di dati. Si noti però che un data.frame ha un'API che può differire dalla sua struttura. Ad esempio, la funzione R row.names può restituire qualcosa di diverso dal valore memorizzato nell'attributo row.names. Penso che la maggior parte delle funzioni .Call funzionino su vettori atomici, mantenendo la manipolazione di oggetti più complicati a livello R.

+0

Questo è esattamente quello che stavo cercando. Grazie Martin. Quali altri attributi di un frame di dati (nrows, rownames, colnames, is.factor ecc.) Posso interrogare quando si passa un DF e si imposta quando si restituisce un DF? RT – user151410

+0

Ho aggiunto alcune frasi su questo alla fine della risposta –

+0

grazie. questo aiuta RT – user151410

3

Ecco un link to an example using C++ and package inline da Dirk Eddelbeuttel:

+0

Grazie per la risposta rapida. C++ non è un'opzione in quanto sono limitato a c dal design. – user151410

+0

Forse guardando il codice per '[<-' ??? –

+0

Perché la restrizione su C? Per R, sei tenuto ad usare gcc il che significa che puoi usare g ++ altrettanto facilmente. Le API più semplici vincono sempre più le API più difficili. Oh, e l'esempio a cui punta DWin può facilmente restituire anche un data.frame. –

0

tipo data.frame è una lista con attributo "data.frame".

Questo è esempio di creazione di data.frame in fonte di R (src/library/statistiche/src/model.c):

/* Turn the data "list" into a "data.frame" */ 
/* so that subsetting methods will work. */ 

PROTECT(tmp = mkString("data.frame")); 
setAttrib(data, R_ClassSymbol, tmp); 
UNPROTECT(1); 

È possibile simulare data.frame manualmente questo way:

l <- list(1:5) 
attr(l, "class") <- "data.frame" 
attr(l, "names") <- "Column 1" 
attr(l, "row.names") <- paste("Row ", 1:5) 
Problemi correlati