[1] "numeric"
[1] "numeric"
[1] "character"
[1] "logical"
[1] "list"
[1] "numeric"
[1] "numeric"
[1] "list"
In every programming language, there are abstract containers for representing different kinds of data and working with them. In classical 3GL programming languages, one distinguishes fundamental, composite, and user-defined data structures.
Fundamental data structures are predefined in the programming language. Typical examples are containers for logical values (TRUE, FALSE), integers (int8), which, for example, represent the 256 values from -128 to 127, floating-point numbers (single, double) with different precision, or characters (a, b), which are often placed in quotation marks. These basic data types are typically associated with suitable operations, such as AND/OR for logical values, + and - for integers, +, -, *, and / for floating-point numbers, or concatenation for characters.
Composite data structures are also predefined and serve to combine several variables of the same type. In R, these include, for example, vectors, lists, arrays, matrices, and data frames. Specific operations also exist for composite structures, such as vector indexing or matrix multiplication.
Finally, in 3GL programming languages, user-defined data structures can also be created. They allow the programming environment to be adapted to specific application cases and are therefore especially relevant in practice. As a rule, they are assembled from predefined structures and, in the context of object-oriented programming, can also be associated with their own operations.
When one learns a programming language, an important first step is to become at least rudimentarily familiar with its data structures. One then gets to know the subtleties of data-structure representation in daily practical work with the programming language. To become familiar with the data structures of a programming language, the following guiding questions are therefore useful:
Fundamental data structures
Composite data structures
User-defined data structures
As a 4GL language, R goes beyond the classical data structures of 3GL languages in its data structures. In R, first of all, everything is an object. Regardless of whether it is a single value, a vector, a function, or a complex data structure, everything is represented by R as an object. In general, the concept of an object denotes the possibility of representing both data and functionality in a single unit of meaning. Here, however, we are primarily interested only in data representation.
In general, one distinguishes in R between atomic objects and recursive objects. Atomic objects consist of components of the same data type. Typical examples are numerical vectors, logical vectors, or character strings. Recursive objects, by contrast, can contain components of different types. These include especially lists and data frames, which make it possible to combine heterogeneous data.
Every R object can be described uniquely by three central properties: its mode, its length, and, optionally, further attributes. The mode of an object specifies the basic data type of an object and is closely related to the type and class of an object, as explained below. In addition to the mode, every object has a length, which indicates how many elements it contains. For a vector, for example, the length is the number of values it contains; for a list, it is the number of its components. In addition, objects in R can be provided with additional attributes. Attributes are metadata that provide additional information about the object, such as the names of elements (names), dimensions (dim) for matrices and arrays, or class information (class), which is relevant for object-oriented programming in R.
Mode, type, and class
The classification of data structures in R is somewhat complex, because the concepts of the mode, the type, and the class of an object exist side by side. In practical application, the subtleties of this classification are usually not important, and the mode, type, and class of an object are also often identical.
Roughly speaking, the mode corresponds to the basic nature of an object and is chosen especially so that there is high compatibility with the data-structure classification system of S (Becker et al. (1988)). Examples of modes are numeric, character, logical, or list. The mode of an object can be retrieved with the function mode(), as the following example shows.
[1] "numeric"
[1] "numeric"
[1] "character"
[1] "logical"
[1] "list"
[1] "numeric"
[1] "numeric"
[1] "list"
Somewhat closer to the internal representation of an object in memory, and therefore somewhat more technical in nature, is the type of an R object. This becomes particularly clear with respect to objects of mode numeric. Here, the classical 3GL type distinctions integer or double exist. Another example is the mode factor. As we will see later, factors in R look to the user like categorical data, often of character type. Their mode, however, is numeric and their type is integer. This is related to the fact that factors in R are often used at the user level to specify experimental conditions that usually have meaningful names such as “Treatment” or “Control”, but in data analysis are represented by mathematical matrices with integer entries. The type of an object can be retrieved with the function typeof(), as the following example shows. Note the similarities and differences with the modes of the same objects called above.
[1] "double"
[1] "integer"
[1] "character"
[1] "logical"
[1] "list"
[1] "integer"
[1] "double"
[1] "list"
Finally, the class of an object specifies the kind of object from the perspective of object-oriented programming in R. For an object, it is especially relevant how generic functions such as print() or summary() deal with it. In contrast to modes and types, programmers can specify the class of objects themselves and thus develop generic functions that are applicable to many kinds of objects and, despite having the same name, carry out different operations with different objects. The class of an object can be retrieved with the function class(), as the following example shows. Note the similarities and differences with the modes and types of the same objects called above.
[1] "numeric"
[1] "integer"
[1] "character"
[1] "logical"
[1] "list"
[1] "factor"
[1] "Date"
[1] "lm"
In summary, the mode describes the general kind of an object, the type describes its internal, technical storage, and the class defines R’s perspective for the functional processing of the object. For many objects, these three concepts agree to a large extent, but for special objects such as factors, date values, or user-defined objects, they differ.