1. 引言
在 R 语言中,数据框(Data Frame)是最重要、最常用的数据结构之一。它类似于 Excel 表格或 SQL 数据库中的表,由行和列组成,每一列可以是不同的数据类型(数值、字符、逻辑等)。无论是数据分析、统计建模还是数据可视化,数据框都是承载数据的核心载体。本文将从数据框的创建、基本操作、索引、类型转换到实战案例,系统性地介绍 R 数据框的方方面面,并提供丰富的可运行代码示例。
2. 数据框的创建
在 R 中,创建数据框有多种方式,最常用的是使用data.frame()函数。下面通过几个示例演示如何创建数据框。
2.1 使用 data.frame() 创建
直接传入向量即可创建数据框,每一列对应一个向量。
# 创建学生成绩数据框 students <- data.frame( name = c("Alice", "Bob", "Charlie", "David"), age = c(20, 21, 22, 23), score = c(85.5, 92.0, 78.5, 88.0), pass = c(TRUE, TRUE, FALSE, TRUE) ) 查看数据框 print(students)运行结果如下:
name age score pass 1 Alice 20 85.5 TRUE 2 Bob 21 92.0 TRUE 3 Charlie 22 78.5 FALSE 4 David 23 88.0 TRUE2.2 使用 tibble 创建
tibble 是 tidyverse 生态中更现代的数据框变体,打印更友好,且不会自动转换字符串为因子。
# 安装并加载 tibble 包 # install.packages("tibble") library(tibble) 创建 tibble students_tbl <- tibble( name = c("Alice", "Bob", "Charlie"), age = c(20, 21, 22), score = c(85.5, 92.0, 78.5) ) print(students_tbl)2.3 从 CSV 文件读取
实际工作中,数据通常从外部文件读取。使用read.csv()或readr::read_csv()可以将 CSV 文件读入为数据框。
# 从 CSV 文件读取数据框 # df <- read.csv("data.csv", stringsAsFactors = FALSE) 使用 readr 包(推荐) install.packages("readr") library(readr) df <- read_csv("data.csv")3. 数据框的基本操作
掌握数据框的基本操作是进行数据分析的前提。下面介绍查看结构、摘要统计和维度信息等常用操作。
3.1 查看数据框结构
# 查看数据框的结构 str(students) 查看前几行 head(students, 2) 查看后几行 tail(students, 2) 查看维度(行数、列数) dim(students) nrow(students) ncol(students)3.2 查看摘要统计
# 查看每列的摘要统计 summary(students)运行结果如下:
name age score pass Length:4 Min. :20.00 Min. :78.50 Mode :logical Class :character 1st Qu.:20.75 1st Qu.:84.25 FALSE:1 Mode :character Median :21.50 Median :86.75 TRUE :3 Mean :21.50 Mean :86.00 3rd Qu.:22.25 3rd Qu.:89.00 Max. :23.00 Max. :92.003.3 查看列名和行名
# 查看列名 names(students) colnames(students) 查看行名 rownames(students)4. 数据框的索引与访问
数据框的索引方式非常灵活,可以使用[]、$或[[ ]]来访问特定行、列或元素。
4.1 使用 [] 索引
# 访问第 1 行第 2 列 students[1, 2] 访问第 1 行所有列 students[1, ] 访问第 2 列所有行 students[, 2] 访问多行多列 students[1:2, c("name", "score")]4.2 使用 $ 访问列
# 使用 $ 访问列(返回向量) students$name students$score4.3 使用 [[ ]] 访问列
# 使用 [[ ]] 访问列(返回向量) students[["age"]] 按列名动态访问 col_name <- "score" students[[col_name]]4.4 逻辑索引
# 筛选成绩大于 85 的学生 students[students$score > 85, ] 筛选年龄小于 22 且通过考试的学生 students[students$age < 22 & students$pass == TRUE, ]5. 数据框的修改与扩展
在实际分析中,经常需要向数据框添加新列、修改已有列或删除列。下面演示这些操作。
5.1 添加新列
# 使用 $ 添加新列 students$grade <- c("B", "A", "C", "A") 使用 transform() 添加计算列 students <- transform(students, score_plus_5 = score + 5) 使用 dplyr 的 mutate()(推荐) install.packages("dplyr") library(dplyr) students <- students %>% mutate(grade2 = ifelse(score >= 90, "A", ifelse(score >= 80, "B", "C"))) print(students)5.2 修改已有列
# 修改某一列的值 students$age <- students$age + 1 使用 within() 修改 students <- within(students, { score <- round(score, 1) })5.3 删除列
# 删除列(将列设为 NULL) students$grade2 <- NULL 使用 subset() 选择保留的列 students_sub <- subset(students, select = c(name, age, score)) 使用 dplyr 的 select() students_sub2 <- students %>% select(name, age, score)6. 数据框的合并与连接
多个数据框之间的合并是数据分析中的常见需求。R 提供了rbind()、cbind()以及merge()等函数。
6.1 按行合并 rbind()
# 创建两个结构相同的数据框 df1 <- data.frame(id = 1:3, value = c(10, 20, 30)) df2 <- data.frame(id = 4:6, value = c(40, 50, 60)) 按行合并 df_combined <- rbind(df1, df2) print(df_combined)6.2 按列合并 cbind()
# 创建两个行数相同的数据框 df_a <- data.frame(id = 1:3, name = c("A", "B", "C")) df_b <- data.frame(score = c(85, 90, 95)) 按列合并 df_full <- cbind(df_a, df_b) print(df_full)6.3 使用 merge() 连接
# 创建两个数据框 students_info <- data.frame( id = 1:4, name = c("Alice", "Bob", "Charlie", "David") ) scores_info <- data.frame( id = c(1, 2, 3, 4), score = c(85.5, 92.0, 78.5, 88.0) ) 按 id 列内连接 merged_df <- merge(students_info, scores_info, by = "id") print(merged_df) 左连接(保留左侧所有行) merged_left <- merge(students_info, scores_info, by = "id", all.x = TRUE)7. 数据框与类型转换
数据框中的列可以是不同类型,有时需要在这些类型之间进行转换。
7.1 向量与数据框的转换
# 向量转数据框 vec <- c(1, 2, 3, 4) df_from_vec <- as.data.frame(vec) print(df_from_vec) 矩阵转数据框 mat <- matrix(1:9, nrow = 3) df_from_mat <- as.data.frame(mat) print(df_from_mat)7.2 列表转数据框
# 列表转数据框 my_list <- list( name = c("Alice", "Bob"), age = c(20, 21) ) df_from_list <- as.data.frame(my_list) print(df_from_list)7.3 数据框转矩阵
# 数据框转矩阵(要求所有列类型一致) df_numeric <- data.frame(a = c(1, 2), b = c(3, 4)) mat_from_df <- as.matrix(df_numeric) print(mat_from_df)8. 实战案例:学生成绩分析
下面通过一个完整的实战案例,综合运用前面介绍的数据框操作,完成一次简单的学生成绩分析。
8.1 创建模拟数据
# 创建模拟学生成绩数据 set.seed(123) # 设置随机种子,保证结果可复现 students <- data.frame( id = 1:20, name = paste0("Student", 1:20), gender = sample(c("M", "F"), 20, replace = TRUE), math = round(runif(20, 60, 100), 1), english = round(runif(20, 60, 100), 1), science = round(runif(20, 60, 100), 1) ) 查看数据 head(students)8.2 数据清洗与计算
# 计算总分和平均分 students$total <- students$math + students$english + students$science students$average <- round(students$total / 3, 2) 根据平均分划分等级 students$grade <- ifelse(students$average >= 90, "A", ifelse(students$average >= 80, "B", ifelse(students$average >= 70, "C", "D"))) 查看结果 head(students)8.3 分组统计
# 使用 dplyr 按性别分组统计 library(dplyr) summary_by_gender <- students %>% group_by(gender) %>% summarise( count = n(), avg_math = mean(math), avg_english = mean(english), avg_science = mean(science), avg_total = mean(total) ) print(summary_by_gender)8.4 筛选与排序
# 筛选平均分大于 80 的学生,并按总分降序排列 top_students <- students %>% filter(average > 80) %>% arrange(desc(total)) print(top_students)9. 常见问题与注意事项
在使用数据框时,有一些常见的坑和注意事项需要了解。
9.1 字符串自动转因子
在旧版 R 中,data.frame()默认会将字符串列转换为因子(Factor)。如果不需要因子,应设置stringsAsFactors = FALSE。
# 避免字符串自动转因子 df <- data.frame(name = c("A", "B"), stringsAsFactors = FALSE) 检查列类型 str(df)9.2 行名与列名的注意事项
# 行名默认是 1, 2, 3... df <- data.frame(x = c(10, 20, 30)) rownames(df) 自定义行名 rownames(df) <- c("row1", "row2", "row3") print(df)9.3 缺失值处理
# 创建包含缺失值的数据框 df_na <- data.frame( x = c(1, 2, NA, 4), y = c(NA, 5, 6, 7) ) 检查缺失值 is.na(df_na) 删除包含缺失值的行 df_clean <- na.omit(df_na) 使用 dplyr 的 drop_na() df_clean2 <- tidyr::drop_na(df_na)10. 总结
本文系统性地介绍了 R 数据框的核心知识,包括数据框的创建、基本操作、索引访问、修改扩展、合并连接、类型转换以及实战案例。数据框作为 R 语言中最核心的数据结构,熟练掌握其操作是进行数据分析和统计建模的基础。建议读者在阅读本文后,动手运行每一个代码示例,并结合自己的实际数据多加练习,这样才能真正掌握数据框的各种操作技巧。