\(~~~~\)Data Structure in R: Data Frame\(~~~~\)

Asst. Prof. Dr. Somsak Chanaim

International College of Digital Innovation, CMU

June 23, 2026

Data Stuctures

Data Stucture in R (ref: First Steps in R)

interactice Data Frame

Input

Data Frame

In R, a data frame is a fundamental data structure used for storing and organizing data in a tabular format.

It’s similar to a table in a database or a spreadsheet in which data is arranged in rows and columns.

Here are a few key points about data frames in R:

  1. Tabular Structure: Data frames consist of rows and columns where each column can hold different types of data (numeric, character, factor, etc.). Rows represent observations, while columns represent variables or attributes.

  2. Mixed Data Types: Unlike matrices, data frames can contain columns with different data types. For instance, one column might contain numeric values, another might have strings, and another might hold categorical data.

  3. Data Manipulation: Data frames allow for easy manipulation, subsetting, and transformation of data using various functions and operations provided by R.

  4. Importing and Exporting Data: R provides functions to import data from various file formats (such as CSV, Excel, etc.) into data frames, making it convenient to work with external datasets. Similarly, data frames can be exported to these formats as well.

How the create the data frame

The data frame is created from multiple vector objects in R by using the data.frame() function.

Example

provide alternative names for variables in a data frame.

The str() function

We can check the structure of a data frame with the str() function.

The results show the following:

  • The number of variables and observation values in the data frame.

  • The types of variables: character, numeric, integer, logical, factor, etc.

The datatable() function from the DT package.

The datatable() function is used to display the data frame in an interactive style and is very useful for HTML output.

Install the DT package

By using datatable() function

The colnames() function

The colnames() function in R is used to get or set the column names of a matrix or data frame.

Example of colnames() function usage

Change the variable “is_Thai” to “is_Chinese”

How to add another variable to the data frame

Use the cbind() function

Another way to add a new variable to the data frame using

How to access/edit the data frame

We can access any value from the data frame in a manner similar to accessing a matrix.

First observation value in the first variable.

All observation values in the first variable.

First 5 observations value from every variables.

Observation 1, 3, and 5 from the variable 1 and 3.

The data frame command to access one variable from the data frame.

Show every value from the second variable.

Show the first 5 observations from the second variable.

How to remove the variable in the data frame

All variables in the data frame Data.

Please Run this code again

To delete the variable letter.

The head(), tail(), and summary() functions

head() function: Return the first n parts of the data frame object.

Show the first 6 observations

Show the first 3 observations

tail() function: Return the last n parts of the data frame object.

Show the last 6 observations

Show the last 4 observations

summary(): Basic descriptive statistics.

Export a data frame to CSV or XLSX files.

  • For export a CSV file, use the readr package.

  • For export an XLSX file, use the writexl package.

1) nstall three packages only once on your computer using RStudio.

install.packages("readr")
install.packages("readxl")
install.packages("writexl")

\(~\)

Load library (Put on the top of your R script)

Export a data frame “Data” to “Data152.csv”

Export a data frame “Data” to “Data152.xlsx”

Import a data frame from csv or xlsx files to R

  • For import a CSV file to R, use the read.csv() function.

  • For import a XLSX file to R, use the readxl package.

Example

tibble vs data frame

Both tibble and data frame are structures used to store tabular data in R, but they differ in behavior and functionality in several ways.

Key Differences between tibble and data frame:

Printing Output

  • data frame: Displays all the data when printed, which can be overwhelming if the dataset is large.

  • tibble: Prints in a more compact format, showing only a few rows and columns that fit the screen, making it cleaner and easier to read.

  • Handles large datasets better.

  • More intuitive printing and subsetting behavior.

  • Reduces errors from partial name matching.

  • Integrates seamlessly with the tidyverse suite of packages.

  • Works well with base R functions.

  • Familiar and widely used for general R programming tasks.

  • No need to load additional packages to work with it.

The subset() function

Subsetting a data frame in R is crucial for several reasons related to data analysis, manipulation, and visualization. Here are some key reasons why subsetting is essential:

1. Extracting Relevant Data:

Data frames often contain a large amount of data.

Subsetting allows you to extract and work with specific rows, columns, or subsets of data that are relevant to your analysis.

This helps in focusing on the relevant parts of the data without being overwhelmed by unnecessary information.

2. Filtering Data:

Subsetting enables you to filter rows based on specific conditions.

For example, you can extract all rows where a certain column meets a criteria (e.g., all customers from a specific city, all transactions above a certain amount).

3. Creating New Data Frames:

Subsetting allows you to create new data frames that contain only the subset of data you are interested in.

This can be useful for creating subsets for different analyses or for sharing specific parts of the data with others.

4. Data Manipulation:

Once you have subsets of data, you can perform various operations such as calculating summary statistics, aggregating data, or creating plots.

Subsetting helps in efficiently manipulating data for these tasks.

5. Improving Performance:

Working with smaller subsets of data can improve the performance of your analysis, especially when dealing with large datasets.

Subsetting allows you to focus computations and visualizations on smaller portions of the data, which can be processed more quickly.

Examples of Subsetting

  • Selecting Columns: Select only some variable in the data frame.

  • Filtering Rows: filters rows based on a condition specified in condition.

  • Slicing: df[row_indices, col_indices] selects specific rows and columns based on indices or logical conditions.(Previous topic)

1. Selecting rows from the mtcars dataset where mpg > 20

2. Selecting rows from the mtcars dataset where mpg > 20 and mpg < 25.

3. From mtcars select the data with mpg > 20 and mpg < 25, then select variable mpg, cyl and disp

Pipe Operation (|>)

The pipe operator |> takes the output from the expression on its left-hand side and passes it as the first argument to the function call on its right-hand side.

This allows you to chain multiple function calls together, where each function operates on the result of the previous one.

Shortcuts Key

MAC: command + shift + m

WINDOWS: crtl +shift + m

Camparing between standard code and using

The standard code

Use pipe operator

Important

We’ll explore the advantages of the pipe operator further in the data wrangling chapter.

Benefits of Using the Pipe Operator

  1. Readability: Code written with the pipe operator reads left-to-right, making it easier to understand the flow of operations.

  2. Code Structure: It allows for a more modular approach to coding, where each step in a data manipulation or analysis pipeline is clear and separate.

  3. Debugging: It simplifies debugging because you can comment out or inspect intermediate steps easily.

  4. Avoiding Nested Functions: It reduces the need for nested function calls (f(g(h(x)))), making the code more readable and maintainable.

Exercise: Data Frame Part 1

Exercise 1: Create a Data Frame

Create a data frame named my_data with columns ID, Name, and Age.

Target output

  ID    Name Age
1  1   Alice  25
2  2     Bob  30
3  3 Charlie  35
4  4   David  40
5  5     Eva  45

Complete the code

my_data <- (
ID = ,
Name = ("Alice", "Bob", "Charlie", "David", "Eva"),
Age = (25, 30, 35, 40, 45)
)
my_data

Exercise 2: Access a Column

Access the Name column from my_data.

Target output

[1] "Alice"   "Bob"     "Charlie" "David"   "Eva"    

Complete the code

my_data <- data.frame(
ID = 1:5,
Name = c("Alice", "Bob", "Charlie", "David", "Eva"),
Age = c(25, 30, 35, 40, 45)
)

name_column <- $
name_column

Exercise 3: Subset Rows Based on a Condition

Subset the rows where Age is greater than 30.

Target output

  ID    Name Age
3  3 Charlie  35
4  4   David  40
5  5     Eva  45

Complete the code

my_data <- data.frame(
ID = 1:5,
Name = c("Alice", "Bob", "Charlie", "David", "Eva"),
Age = c(25, 30, 35, 40, 45)
)

(, subset = > )

Exercise 4: Add a New Column

Add a new column named Salary to my_data with values 50000, 55000, 60000, 65000, and 70000.

Target output

  ID    Name Age Salary
1  1   Alice  25  50000
2  2     Bob  30  55000
3  3 Charlie  35  60000
4  4   David  40  65000
5  5     Eva  45  70000

Complete the code

my_data <- data.frame(
ID = 1:5,
Name = c("Alice", "Bob", "Charlie", "David", "Eva"),
Age = c(25, 30, 35, 40, 45)
)

$ <- (50000, 55000, 60000, 65000, 70000)
my_data

Exercise 5: Rename Columns

Rename columns ID to EmployeeID and Name to EmployeeName. Show only rows 1 to 3.

Target output

  EmployeeID EmployeeName Age Salary
1          1        Alice  25  50000
2          2          Bob  30  55000
3          3      Charlie  35  60000

Complete the code

my_data <- data.frame(
ID = 1:5,
Name = c("Alice", "Bob", "Charlie", "David", "Eva"),
Age = c(25, 30, 35, 40, 45),
Salary = c(50000, 55000, 60000, 65000, 70000)
)

() <- ("EmployeeID", "EmployeeName", "Age", "Salary")
(, )

Exercise 6: Remove a Column

Remove the Salary column from my_data.

Target output

  ID    Name Age
1  1   Alice  25
2  2     Bob  30
3  3 Charlie  35
4  4   David  40
5  5     Eva  45

Complete the code

my_data <- data.frame(
ID = 1:5,
Name = c("Alice", "Bob", "Charlie", "David", "Eva"),
Age = c(25, 30, 35, 40, 45),
Salary = c(50000, 55000, 60000, 65000, 70000)
)

$ <- NULL
my_data

Exercise 7: Sort the Data Frame

Sort my_data by the Age column in descending order.

Target output

  ID    Name Age
5  5     Eva  45
4  4   David  40
3  3 Charlie  35
2  2     Bob  30
1  1   Alice  25

Complete the code

my_data <- data.frame(
ID = 1:5,
Name = c("Alice", "Bob", "Charlie", "David", "Eva"),
Age = c(25, 30, 35, 40, 45)
)

sorted_data <- [(-$), ]
sorted_data

Exercise 8: Merge Two Data Frames

Create my_data2 and merge it with my_data using EmployeeID.

Target output

  EmployeeID EmployeeName Age Department
1          1        Alice  25         HR
2          2          Bob  30         IT
3          3      Charlie  35    Finance
4          4        David  40  Marketing
5          5          Eva  45      Sales

Complete the code

my_data <- data.frame(
EmployeeID = 1:5,
EmployeeName = c("Alice", "Bob", "Charlie", "David", "Eva"),
Age = c(25, 30, 35, 40, 45)
)

my_data2 <- (
EmployeeID = ,
Department = ("HR", "IT", "Finance", "Marketing", "Sales")
)

merged_data <- (, , by = "")
merged_data

Exercise 9: Calculate Summary Statistics

Calculate the mean age of employees in my_data.

Target output

[1] 35

Complete the code

my_data <- data.frame(
EmployeeID = 1:5,
EmployeeName = c("Alice", "Bob", "Charlie", "David", "Eva"),
Age = c(25, 30, 35, 40, 45)
)

mean_age <- ($)
mean_age

Exercise 10: Filter and Select Specific Columns

Select EmployeeName and Department columns for employees in the IT department.

Target output

  EmployeeName Department
2          Bob         IT

Complete the code

merged_data <- data.frame(
EmployeeID = 1:5,
EmployeeName = c("Alice", "Bob", "Charlie", "David", "Eva"),
Department = c("HR", "IT", "Finance", "Marketing", "Sales")
)

it_department <- merged_data |>
( == "") |>
(select = ("EmployeeName", "Department"))
it_department

Exercise: Data Frame Part 2

Exercise 11: Basic Row Binding

Use rbind() to combine df1 and df2 into a single data frame.

Target output

  A B
1 1 X
2 2 Y
3 3 Z
4 4 W
5 5 V
6 6 U

Complete the code

df1 <- data.frame(A = 1:3, B = c("X", "Y", "Z"))
df2 <- data.frame(A = 4:6, B = c("W", "V", "U"))

combined_df <- (, )
combined_df

Exercise 12: Column Binding with Matching Rows

Use cbind() to combine df1 and df2 into one data frame.

Target output

  A B     C    D
1 1 X  TRUE 10.5
2 2 Y FALSE 20.5
3 3 Z  TRUE 30.5

Complete the code

df1 <- data.frame(A = 1:3, B = c("X", "Y", "Z"))
df2 <- data.frame(C = c(TRUE, FALSE, TRUE), D = c(10.5, 20.5, 30.5))

combined_df <- (, )
combined_df

Exercise 13: Subsetting by Condition

Use subset() to extract rows where column B is greater than 30.

Target output

    A  B
7   7 35
8   8 40
9   9 45
10 10 50

Complete the code

df <- data.frame(A = 1:10, B = c(5, 10, 15, 20, 25, 30, 35, 40, 45, 50))

subset_df <- (, > )
subset_df

Exercise 14: Adding a New Row

Add new_row to df using rbind().

Target output

  A B
1 1 X
2 2 Y
3 3 Z
4 4 W

Complete the code

df <- data.frame(A = 1:3, B = c("X", "Y", "Z"))
new_row <- data.frame(A = 4, B = "W")

updated_df <- (, )
updated_df

Exercise 15: Adding a New Column

Add new_column to df using cbind().

Target output

  A B  C
1 1 X 10
2 2 Y 20
3 3 Z 30

Complete the code

df <- data.frame(A = 1:3, B = c("X", "Y", "Z"))
new_column <- data.frame(C = c(10, 20, 30))

updated_df <- (, )
updated_df

Exercise 16: Combining Data Frames with Different Columns

Add missing columns with NA values, then combine df1 and df2 using rbind().

Target output

   A    B  C    D
1  1    X NA <NA>
2  2    Y NA <NA>
3  3    Z NA <NA>
4 NA <NA>  4    W
5 NA <NA>  5    V
6 NA <NA>  6    U

Complete the code

df1 <- data.frame(A = 1:3, B = c("X", "Y", "Z"))
df2 <- data.frame(C = 4:6, D = c("W", "V", "U"))

df1$C <-
df1$D <-
df2$A <-
df2$B <-
combined_df <- (, )
combined_df

Exercise 17: Subsetting Specific Columns

Use subset() to select columns A and C from df.

Target output

  A     C
1 1  TRUE
2 2 FALSE
3 3  TRUE
4 4 FALSE
5 5  TRUE

Complete the code

df <- data.frame(A = 1:5, B = c("X", "Y", "Z", "W", "V"), C = c(TRUE, FALSE, TRUE, FALSE, TRUE))

subset_df <- (, select = (, ))
subset_df

Exercise 18: Conditional Row Binding

Use a condition to select rows from df2, then combine them with df1 using rbind().

Target output

   A B
1  1 X
2  2 Y
3  3 Z
21 5 V
31 6 U

Complete the code

df1 <- data.frame(A = 1:3, B = c("X", "Y", "Z"))
df2 <- data.frame(A = 4:6, B = c("W", "V", "U"))

df2_subset <- (, > )
combined_df <- (, )
combined_df

Exercise 19: Subsetting Rows by Multiple Conditions

Use subset() to extract rows where A > 5 and B < 40.

Target output

  A  B
6 6 30
7 7 35

Complete the code

df <- data.frame(A = 1:10, B = c(5, 10, 15, 20, 25, 30, 35, 40, 45, 50))

subset_df <- (, > & < )
subset_df

Exercise 20: Combining with Different Row Numbers

Modify df2 to have the same number of rows as df1, then combine them using cbind().

Target output

  A B     C
1 1 X  TRUE
2 2 Y FALSE
3 3 Z  TRUE
4 4 W    NA

Complete the code

df1 <- data.frame(A = 1:4, B = c("X", "Y", "Z", "W"))
df2 <- data.frame(C = c(TRUE, FALSE, TRUE, ))

combined_df <- (, )
combined_df

Exercise 21: View Data Structure

Use str() to view the structure of my_data.

Target output

'data.frame':   5 obs. of  3 variables:
 $ EmployeeID  : int  1 2 3 4 5
 $ EmployeeName: chr  "Alice" "Bob" "Charlie" "David" ...
 $ Age         : num  25 30 35 40 45

Complete the code

my_data <- data.frame(EmployeeID=1:5, EmployeeName=c('Alice','Bob','Charlie','David','Eva'), Age=c(25,30,35,40,45))

()

Exercise 22: Check Missing Values

Count the total number of missing values in my_data.

Target output

[1] 2

Complete the code

my_data <- data.frame(A=c(1,2,NA,4), B=c('X', NA, 'Z', 'W'))

missing_count <- (())
missing_count

Exercise 23: Remove Missing Values

Remove rows containing missing values from my_data.

Target output

  A B
1 1 X
4 4 W

Complete the code

my_data <- data.frame(A=c(1,2,NA,4), B=c('X', NA, 'Z', 'W'))

clean_data <- ()
clean_data

Exercise 24: Sort by Multiple Columns

Sort df by column A ascending and column B descending.

Target output

  A  B
2 1 20
1 1 10
3 2 15
4 2  5

Complete the code

df <- data.frame(A=c(1,1,2,2), B=c(10,20,15,5))

sorted_df <- df[(df$A, -df$B), ]
sorted_df

Exercise 25: Apply Function to Columns

Use sapply() to find the class of each column in my_data.

Target output

  EmployeeID EmployeeName          Age 
   "integer"  "character"    "numeric" 

Complete the code

my_data <- data.frame(EmployeeID=1:5, EmployeeName=c('Alice','Bob','Charlie','David','Eva'), Age=c(25,30,35,40,45))

column_classes <- (, )
column_classes