Есть ли общий способ передачи кадра данных с произвольными столбцами (integer/factor, numeric, character data) от r до c и обратно? Было бы очень полезно оценить указатели на достаточно близкие примеры.
Спасибо.
РТ
Есть ли общий способ передачи кадра данных с произвольными столбцами (integer/factor, numeric, character data) от r до c и обратно? Было бы очень полезно оценить указатели на достаточно близкие примеры.
Спасибо.
РТ
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.
Здесь ссылка на пример с использованием С++ и пакетной строки от Dirk Eddelbeuttel:
Тип data.frame - это список с атрибутом data.frame.
Это пример создания data.frame в источнике R (src/library/stats/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);
Вы можете имитировать data.frame вручную следующим образом:
l <- list(1:5)
attr(l, "class") <- "data.frame"
attr(l, "names") <- "Column 1"
attr(l, "row.names") <- paste("Row ", 1:5)