2011-07-12 40 views

回答

15

一個data.frame是一個列表,所以沿

#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; 
} 

行再經過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" 

使用GET_CLASS,GET_ATTR和Rdefines.h中的其他宏(或其等價函數,如getAttrib)來發現有關數據框的其他信息。請注意,data.frame的API可能與其結構不同。因此,例如R函數row.names可以返回與row.names屬性中存儲的值不同的內容。我認爲大多數.Call函數在原子向量上運行,保持對R級更復雜對象的操縱。

+0

這正是我所期待的。感謝Martin。數據框的其他屬性(nrows,rownames,colnames,is.factor等)可以在傳遞DF時進行查詢並在返回DF時進行設置? RT – user151410

+0

我加了幾句關於這個答案的結尾 –

+0

謝謝。這有助於。 RT – user151410

3

這裏有一個link to an example using C++ and package inline德克Eddelbeuttel:

+0

感謝您的快速響應。 C++不是一個選項,因爲我被設計限制爲c。 – user151410

+0

也許正在看''<?'的代碼? –

+0

爲什麼對C的限制?對於R,你必然會使用gcc,這意味着你可以輕鬆地使用g ++。更簡單的API每次勝過更難的API。哦,並且由DWin指出的例子也可以輕鬆地返回數據幀。 –

0

data.frame類型是一個帶有「data.frame」屬性的列表。

這是實施例中的R (SRC /庫/統計/ SRC/model.c)的源創建data.frame的:

/* 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); 

可以模擬 data.frame手動此方式:

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