Which data type is closest to C struct in R

Viewed 3673

Is there any way I could use the C struct in R, or any alternative? What I'm searching is a data type that can handle different types of data, and grant access in a understandable way. R lists already does this, but the access of the content are by indexes [[ ]]. It seems messy to deal with it, because I have to remember what exactly is on the first element, seconds, etc. The c struct is good example, as the content is accessed with . operator, and the programmer doesn't has to think what the [[nth]] saves.

E.g:

struct MyStuct{
    int powerLevel;
    int size;
} //create the data type

struct Mystruct variable;  //instantiate the object
variable.size  //access the content of the object

So, what I want is a data type for storing points of a time series, its SSE, the group, the K used for K means, and other content in a single variable. The closest I think of is the C struct.

3 Answers

C structure accessed with a dot (.)

struct MyStruct{
    int powerLevel;
    int size;
} variable;  
variable.size; 

Similar R Code accessed with a barred S ($)

variable = list(
     powerlevel = 0,
     size = 0
)
variable$size

You might want to look at using R::setClass

Essentially, this allows you to create a class definition and return a generator function to create objects from the class. Personally, I find it very useful in the context you describe. To dereference a structure component you can use @, using the example below CStructure@powerLevel will return 5

As an alternative, one might consider using a dataframe, however, the dataframe approach does not create an independent class template. It also requires all entries to be the same length. A dataframe is symmetrical, your data may not be.

See example error ref: Dataframe's have to be symmetrical detailed below the example using setClass. That said both are options.

I hope the example is useful to you.

Example

setClass(
  "CStruct",
  slots = list(
    powerLevel = "numeric",
    size = "numeric"
  )
)

CStructure <- new("CStruct", powerLevel =5, size=10)
CStructure
str(CStructure)
CStructure@powerLevel
CStructure@size

Output:

> setClass(
+   "CStruct",
+   slots = list(
+     powerLevel = "numeric",
+     size = "numeric"
+   )
+ )
> 
> CStructure <- new("CStruct", powerLevel =5, size=10)
> CStructure
An object of class "CStruct"
Slot "powerLevel":
[1] 5

Slot "size":
[1] 10

> str(CStructure)
Formal class 'CStruct' [package ".GlobalEnv"] with 2 slots
  ..@ powerLevel: num 5
  ..@ size      : num 10
> CStructure@powerLevel
[1] 5
> CStructure@size
[1] 10
> 

Dataframe's have to be symmetrical

> n = c(2, 3, 5)
> s = c("aa", "bb")
> b = c(TRUE, FALSE, TRUE)
> df = data.frame(n, s, b)
Error in data.frame(n, s, b) : 
  arguments imply differing number of rows: 3, 2

CStruct Alternative

setClass(
  "CStruct2",
  slots = list(
   n = "numeric",
   s = "character",
   b = "logical"
  )
)

CStructure2 <- new("CStruct2", n = c(2, 3, 5), 
                  s = c("aa", "bb"), 
                  b = c(TRUE, FALSE, TRUE) )
str(CStructure2)
CStructure2@n
CStructure2@s
CStructure2@b

Output:

> setClass(
+   "CStruct2",
+   slots = list(
+    n = "numeric",
+    s = "character",
+    b = "logical"
+   )
+ )
> 
> CStructure2 <- new("CStruct2", n = c(2, 3, 5), 
+                   s = c("aa", "bb"), 
+                   b = c(TRUE, FALSE, TRUE) )
> str(CStructure2)
Formal class 'CStruct2' [package ".GlobalEnv"] with 3 slots
  ..@ n: num [1:3] 2 3 5
  ..@ s: chr [1:2] "aa" "bb"
  ..@ b: logi [1:3] TRUE FALSE TRUE    
> CStructure2@n

[1] 2 3 5
> CStructure2@s
[1] "aa" "bb"
> CStructure2@b
[1]  TRUE FALSE  TRUE
> n = c(2, 3, 5) 
> s = c("aa", "bb", "cc") 
> b = c(TRUE, FALSE, TRUE) 
> df = data.frame(n, s, b) 

Data frame can store vectors.

Related