Menu

R 数据框:创建、查看和访问列

数据框就是 R 里的电子表格:一组等长的具名列,每列有自己的类型。本文讲怎么创建数据框,怎么用 str() 和 head() 快速了解它,以及怎么取出列、行和单元格。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

数据框是由列组成的列表

数据框是 R 的表格:每行是一条观测,每列是一个变量。它就是 R 里的电子表格,几乎所有真实数据都是这个形状:每个人、每次测量、每笔交易占一行,每个属性占一列。

从结构上看,数据框是一个由等长向量组成的列表,再加上行和列的行为。这一点能解释它的大部分规则:每列只有一种类型(因为列是向量),不同的列可以有不同的类型(因为数据框是列表),而且每列长度必须相同(这就是“框”的含义)。

把具名向量交给 data.frame() 就能创建一个数据框:

文本、数字和逻辑值并排放在一起,这是矩阵做不到的。实际上你很少会像这样手动输入数据,表格通常来自 read.csv 或数据库。但无论数据框从哪里来,下面的内容都完全适用。

快速了解一个数据框

没看过的数据集,千万别直接拿来计算。R 用来查看数据的工具不多,值得养成随手就用的习惯:

  • str() 是拿到新数据后第一个要运行的:每列一行,显示类型和前几个值。如果某列“数字”因为混进一个异常值而被读成了 character,你在这里就能发现。
  • nrow() / ncol() 给出维度;names() 列出所有列名。
  • summary() 给出每列的统计信息:数值列有最小值、中位数、平均值、最大值,逻辑列和因子列有计数。
  • head(df) 和 tail(df) 打印前六行和后六行,当真实数据集大到无法整个打印时,它们必不可少。下面你会在一个内置数据集上看到 head() 的用法。

取出一列的三种写法

访问列是最常用的操作,R 提供了三种写法:

  • people$age:日常写法,简短易读,大多数编辑器都能自动补全。
  • people[["age"]]:结果完全相同,但列名可以来自变量(col <- "age"; people[[col]]),这是 $ 做不到的。在函数内部优先用它。
  • people[, "age"]:矩阵风格,逗号前是行(留空表示全部),逗号后是列。

三者都把这一列作为普通向量返回,可以直接用于 mean(people$age)。代码片段里的第四种写法是个陷阱:用单层方括号的 people["age"] 返回的是只有一列的数据框,而不是向量。这和列表中 [ 与 [[ 的区别是一回事,因为数据框本身就是列表。如果某个数学函数抱怨你的输入不是数值,先检查一下方括号。

行和单元格

用 [row, column] 写法可以取出表格的任意部分:

people[2, ] 是整个第二行(返回一个单行数据框;行里混合了多种类型,所以仍然保持数据框的形式)。people[2, "name"] 是单个单元格。用一个行号向量可以一次取出多行。

最后一行最重要:对某列写一个逻辑条件,就能选出符合条件的行,这里选出的是所有年龄超过 28 岁的人。这种用逻辑掩码筛选行的模式是 R 中所有数据筛选的基础,值得单独写一篇:完整讲解请看筛选与子集,包括 subset() 和多条件筛选。

添加和删除列

因为数据框是由列组成的列表,所以列的增删只需普通的赋值:

给新的列名赋值就会添加一列;向量长度必须等于 nrow()(或者长度为 1,会循环填满每一行)。第二次添加展示了地道的做法:用已有的列计算出新列,向量化运算一次作用于整列。赋值 NULL 会把一列彻底删除。

列中的值也可以用同样的方式覆盖:people$age <- people$age + 1 让每个人都长了一岁。

内置数据集,以及 tibble 简介

R 自带一些预先加载好的练习数据集,所以上面的内容你不用导入任何东西就能试。几乎每个教程都会用到的两个是 mtcars(32 辆汽车,11 个数值变量)和 iris(150 朵花,4 项测量值加一个表示品种的因子):

这里能看出 head() 的价值:六行就能让你了解数据的形状,又不会刷满屏幕。这些数据集是理想的练习场:当你不确定某个函数的行为时,先在 mtcars 上试一试,再用到自己的数据上。

一接触 tidyverse 你就会遇到一个术语:tibble,它是 tidyverse 版本的数据框。概念相同,行为更友好:打印时只显示前十行和各列类型,也不会对列名做部分匹配。用 tibble() 创建,或者由 readr/dplyr 的函数返回:

library(tibble)
tibble(name = c("Rosa", "Ken"), age = c(30, 41))
#> # A tibble: 2 x 2
#>   name    age
#>   <chr> <dbl>
#> 1 Rosa     30
#> 2 Ken      41

本文的所有内容($、str()、添加列、逻辑行掩码)在 tibble 上都照样适用。tibble 本质上就是打磨过的数据框;学会了数据框,两者你就都会了。

要点总结

  • 数据框是由等长列组成的列表:每列一种类型,整个表格可以混合多种类型,它就是 R 的电子表格。
  • 先查看再计算:先用 str(),再用 head()、summary()、nrow()/ncol()/names()。
  • df$col、df[["col"]] 和 df[, "col"] 都把列作为向量返回;单层方括号的 df["col"] 返回数据框。
  • df[rows, cols] 可以切出任意部分;逗号前写逻辑掩码就能筛选行。
  • 用赋值添加列(常常由其他列计算得出);用 NULL 删除列;用 mtcars 练手。

下一篇:缺失值,讲 NA 的含义、它为什么会在计算中扩散,以及该如何处理它。

常见问题

在 R 中怎么创建数据框?

把等长的具名向量传给 data.frame():df <- data.frame(name = c("Rosa", "Ken"), age = c(30, 41))。每个向量成为一列。实际工作中,大多数数据框都不是手动输入的,而是来自 read.csv() 或数据库,但结构完全一样。

怎么访问 R 数据框中的一列?

有三种写法:df$age(简洁易读)、df[["age"]](结果相同,列名存在变量里时也能用)、df[, "age"](矩阵风格)。三者都把这一列作为普通向量返回。而用单层方括号的 df["age"] 返回的是只有一列的数据框,这是一个常见的困惑来源。

str() 对数据框会显示什么?

每列一行:列名、类型和前几个值,顶部还有行数和列数。这是看清某列被读成数值还是文本的最快方法,所以拿到任何新加载的数据集,第一件事就应该运行 str()。

怎么给 R 数据框添加一列?

给一个还不存在的列名赋值:df$score <- c(88, 75, 93)。向量长度必须等于行数(或者长度为 1,会循环填满每一行)。要删除一列,就给它赋值 NULL:df$score <- NULL。

Coddy 编程语言插图

和 Coddy 一起学编程

开始