Short answer
From the documentation - example
df=REvaluate["
{
age <- 18:23
height <- c(76.1,77,78.1,78.2,78.8,79.7)
name <- c(\"John Young\",\"Jane Ty\",\"john Ed\",\"Mary Ann\",\"Thomas Ed\",\"John Wood\")
village <- data.frame(age=age,height=height,name=name)
as.data.frame(village)
}
"]
(*
RDataFrame[RNames[age,height,name],RData[{18,19,20,21,22,23},
{76.1,77.,78.1,78.2,78.8,79.7},RFactor[{4,1,2,5,6,3},
RFactorLevels[Jane Ty,john Ed,John Wood,John Young,Mary Ann,Thomas Ed]]],
RRowNames[1,2,3,4,5,6]
]
*)
Now,
RGetData[df]
(*
{{18,19,20,21,22,23}, 76.1,77.,78.1,78.2,78.8,79.7},
RFactor[{4,1,2,5,6,3},RFactorLevels[Jane Ty,john Ed,John Wood,John Young,
Mary Ann,Thomas Ed]]}
*)
This extracts the names.
RGetNames[df]
(* {age,height,name} *)
This extracts the row names.
RGetRowNames[df]
(* {1,2,3,4,5,6} *)
Long answer
RDataFrame (as well as RFactor) are two data types implemented via RLink type extension mechanism. In this sense, there is no difference between them being implemented by the RLink developer, or the user. The relevant tutorial is R Data types in RLink, the second large section on type extension mechanism. It contains a detailed walk-through for the procedure of defining new types.
The support for data frames and factors currently is very basic. Basically, apart from a few simple data transformations and display functions, such as TableForm, not much is in there. In time, this support will probably become better, but you don't have to wait until then - you can implement your own extensions or extend those implementations. The full source code for RDataFrame and RFactor implementation is available at
FileNameJoin[{$InstallationDirectory,"SystemFiles","Links","RLink","Kernel","DataTypes","Base.m"}]
To answer your specific question, the relevant part of this implementation for a data frame looks like
RDataFrame /: RGetNames[ RDataFrame[RNames[names___],__]] := {names};
RDataFrame /: RGetAttributes[ RDataFrame[__,a : (_RAttributes | None) : None]]:=
RGetAllAttributes[a];
RDataFrame /:
RGetRowNames[
RDataFrame[
_,
RData[data__],
rnames : (RRowNames[rn__] | Automatic) : Automatic,
a : (RAttributes[__] | None) : None
]]:=
If[rnames === Automatic, Range[Length[{data}]],{rn}];
RDataFrame /: RGetData[RDataFrame[_, RData[data__],___]]:= {data};
which both tells you how to extract the data parts (which heads are responsible for this), and how this has been implemented. That's all there is to it currently. The data extractors like RGetNames, RGetAttributes, RGetData, RGetRowNames are universal heads which are overloaded by various data types, and currently placed at
FileNameJoin[{$InstallationDirectory,"SystemFiles","Links","RLink","Kernel","DataTypes","Common.m"}]
The overloading for specific data types is done via UpValues, which is the recommended way to do this for user-defined types. This way such implementations will be independent for 2 different users.
How these data extractor heads work for data frames is illustrated in the mentioned tutorial. If you want to extend the current functionality, you have two choices: either create a package that would extend the current functionality, or unregister current implementations of RDataFrame etc via RDataTypeUnregister function and create a package with your own implementations, which would replace the existing ones and which you can inform Rlink about via the "AddToRDataTypePath" option (which is accepted by both InstallR and RDataTypeDefinitionsReload - the latter being a specific tool to enable to to pick up new definitions from files without quitting the RLink session).
It has been discussed in chat already that it would be nice to have a way to share such new data type implementations between RLink users. All I can say at the moment is that work is underway to enable that.