Передача фрейма данных из-в R и C с использованием .call () - PullRequest
11 голосов
/ 12 июля 2011

Существует ли общий способ передачи фрейма данных с произвольными столбцами (целочисленные / факторные, числовые, символьные данные) из r в c и обратно?Мы будем очень признательны за указатели, чтобы закрыть достаточно примеров.

Спасибо.

RT

Ответы [ 3 ]

16 голосов
/ 12 июля 2011

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.

3 голосов
/ 12 июля 2011
1 голос
/ 02 апреля 2015

тип 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...