跳至内容
R
数据科学

在 R 中对子集数据集

对子集数据集是每位数据从业者的关键技能。通过这个简短的交互式教程学习并练习数据子集化!
Tom Jeon's photo
Tom Jeon
已更新 · 6分钟 阅读

使用 AI 探索

ChatGPTClaudePerplexity

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续
继续操作即表示您接受我们的《使用条款》和《隐私政策》,并同意您的数据存储在美国。

无论您是在比较不同人群对营销活动的反应、聚焦某个特定时间段,还是从库存中提取少数几种产品的信息,给数据集做子集都能帮助您从数据中提取有用的观察。R 是一款让数据子集化变得简单直观的优秀工具。完成本教程后,您将掌握从数据集中提取所需信息的要领。

对子集化并不会改变数据的内容,只是选出与您的目标最相关的那一部分。一般来说,行和列的子集有三种方式——按索引、按名称和按取值。

按索引子集行与列

一种方法是按数据集的索引来对子集行与列。这就像把行和列描述为“第一行”“第二和第五列的所有行”或“第二到第五列的第一行”。我们用 R 中名为 iris 的数据集来说明这些说法。根据其文档,"这份著名的(Fisher 或 Anderson 的)鸢尾花数据集分别给出了三种鸢尾花各 50 朵样本的萼片长度与宽度、花瓣长度与宽度(单位:厘米)。物种为 Iris setosa、versicolor 和 virginica。"

# "The first row": iris[1, ] # "All rows in second and fifth columns": iris[, c(2, 5)] # "The first row in second to fifth columns": iris[1, 2:5]

要对子集数据,在数据集对象后使用方括号。方括号内第一个元素指定行,第二个元素指定列,两者之间用逗号分隔:

data[rows, columns]

按名称子集行与列

在 R 中,数据集的行和列都有名称属性。行名很少使用,默认提供索引——从 1 到数据集行数的整数——就像上一节所见。事实上,如果对 iris 调用 rownames(),您会发现它们只是从 1 到 150 的索引:

 > rownames(iris)
[1] "1"   "2"   "3"   "4"   "5"   "6"   "7"   "8"   "9"   "10"  "11"  "12"  "13"  "14"
[15] "15"  "16"  "17"  "18"  "19"  "20"  "21"  "22"  "23"  "24"  "25"  "26"  "27"  "28"
[29] "29"  "30"  "31"  "32"  "33"  "34"  "35"  "36"  "37"  "38"  "39"  "40"  "41"  "42"
[43] "43"  "44"  "45"  "46"  "47"  "48"  "49"  "50"  "51"  "52"  "53"  "54"  "55"  "56"
[57] "57"  "58"  "59"  "60"  "61"  "62"  "63"  "64"  "65"  "66"  "67"  "68"  "69"  "70"
[71] "71"  "72"  "73"  "74"  "75"  "76"  "77"  "78"  "79"  "80"  "81"  "82"  "83"  "84"
[85] "85"  "86"  "87"  "88"  "89"  "90"  "91"  "92"  "93"  "94"  "95"  "96"  "97"  "98"
[99] "99"  "100" "101" "102" "103" "104" "105" "106" "107" "108" "109" "110" "111" "112"
[113] "113" "114" "115" "116" "117" "118" "119" "120" "121" "122" "123" "124" "125" "126"
[127] "127" "128" "129" "130" "131" "132" "133" "134" "135" "136" "137" "138" "139" "140"
[141] "141" "142" "143" "144" "145" "146" "147" "148" "149" "150"

> nrow(iris)
[1] 150

行名在较小的数据集中更常见,用于使数据集中的观测易于辨认。例如,对于一个包含某位医生病人健康信息的小型数据集,其行名可以是病人的全名。

另一方面,列名几乎在任何数据集中都存在。您可以使用 colnames() 或 names() 函数获取它们:

colnames(iris)
[1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"     

names(iris)
[1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"

要按行和列的名称对子集数据集,只需再次使用方括号,前面加上数据集对象:

# 第五条观测的萼片宽度 iris["5", "Sepal.Width"] # 萼片宽度与花瓣宽度 iris[, c("Sepal.Width", "Petal.Width")]

需要注意的是,行名和列名都是字符,因此必须使用单引号或双引号!

按取值子集行与列

按取值对子集行与列往往最灵活。比如,您可以用如下条件语句提取 Iris setosa 的数据:

> iris[iris$Species == "setosa", ]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           5.1         3.5          1.4         0.2  setosa
2           4.9         3.0          1.4         0.2  setosa
3           4.7         3.2          1.3         0.2  setosa
4           4.6         3.1          1.5         0.2  setosa

...

47          5.1         3.8          1.6         0.2  setosa
48          4.6         3.2          1.4         0.2  setosa
49          5.3         3.7          1.5         0.2  setosa
50          5.0         3.3          1.4         0.2  setosa

像 iris$Species == "setosa" 这样的条件语句应放在方括号中的行元素位置(即逗号前的第一个元素)。除了在第一个元素中使用条件语句外,您还可以在第二个元素中按索引或名称指定列。请在下面的控制台中试着只选出 Iris setosa 的萼片测量值:

# 打印 setosa 的萼片测量值 # 打印 setosa 的萼片测量值(按名称) iris[iris$Species == "setosa", c("Sepal.Length", "Sepal.Width")] # 打印 setosa 的萼片测量值(按索引) iris[iris$Species == "setosa", 1:2] test_or( test_output_contains('iris[iris$Species == "setosa", c("Sepal.Length", "Sepal.Width")]', incorrect_msg = "Select just the Sepal.Length and Sepal.Width columns for the setosa iris either by name or index."), test_output_contains('iris[iris$Species == "setosa", c("Sepal.Width", "Sepal.Length")]', incorrect_msg = "Select just the Sepal.Length and Sepal.Width columns for the setosa iris either by name or index.")) success_msg("Great work!")

回顾

在本教程中,您:

  • 学习了按索引对子集数据框。行和列分别从 1 到相应的数量进行整数索引。
  • 学习了按名称对子集数据框。您了解到行名很少单独设置,而列名是字符类型。
  • 学习了在方括号的行元素中使用条件语句,按取值对子集数据框。
  • 学习了结合这些方法以实现更灵活的子集化(例如,对行使用条件,对列按索引或名称子集)。

下面是一些练习,帮助巩固您所学的内容。熟能生巧,动手试试吧!

练习题

选出所有萼片宽度大于花瓣长度的观测。

# 哪些观测的萼片宽度大于花瓣长度? # 哪些观测的萼片宽度大于花瓣长度? iris[iris$Sepal.Width > iris$Petal.Length, ] test_output_contains('iris[iris$Sepal.Width > iris$Petal.Length, ]', incorrect_msg = paste("Select the observations for which Sepal.Width values", "are larger than Petal.Length values.")) success_msg("Nice! Turns out only Iris setosa have this shape.")
在方括号内使用 iris$Sepal.Width > iris$Petal.Length。别忘了逗号!

选出所有 Iris versicolor 中,萼片宽度大于所有物种平均萼片宽度的观测。

# 将 versicolor 数据存为名为 versicolor 的对象 # 选出所有萼片宽度高于平均值的 Iris versicolor # 将 versicolor 数据存为名为 versicolor 的对象 versicolor <- iris[iris$Species == "versicolor", ] # 选出所有萼片宽度高于平均值的 Iris versicolor versicolor[versicolor$Sepal.Width > mean(iris$Sepal.Width), ] test_object('versicolor', undefined_msg = "Did you define the versicolor object?", incorrect_msg = paste("Select where Species is equal to \"versicolor\".", "Remember to use the == operator!")) test_output_contains('versicolor[versicolor$Sepal.Width > mean(iris$Sepal.Width), ]', incorrect_msg = paste("Not quite! Are you using the mean() function", "to find the average sepal width across all species", "and not just for Iris versicolor?")) success_msg("Great work!")
使用 mean() 函数计算 iris 中的平均萼片宽度,然后以 versicolor 为前缀写条件语句,只选出高于平均值的观测。

报告所有花瓣长度小于 5 厘米的 Iris virginica 的平均萼片宽度。

# 您可以用任何您喜欢的方法来解决! # 将 virginica 数据存为名为 virginica 的对象 virginica <- iris[iris$Species == "virginica", ] # 花瓣长度小于 5 的 Iris virginica 的平均萼片宽度 mean(virginica[virginica$Petal.Length < 5, ]$Sepal.Width) test_output_contains('2.8', incorrect_msg = "Incorrect! This is a tough one!") success_msg("Excellent!")
首先尝试对子集出所有 Iris virginica,然后筛选 Petal.Length 小于 5 的观测。调用 mean() 函数即可求平均值。

想进一步了解从数据中提取洞见的其他方法?请查看 DataCamp 上这些课程!

看看我们的 在 R 中合并数据集 教程。

无论您是在比较不同人群对营销活动的反应、聚焦某个特定时间段,还是从库存中提取少数几种产品的信息,给数据集做子集都能帮助您从数据中提取有用的观察。R 是一款让数据子集化变得简单直观的优秀工具。完成本教程后,您将掌握从数据集中提取所需信息的要领。

对子集化并不会改变数据的内容,只是选出与您的目标最相关的那一部分。一般来说,行和列的子集有三种方式——按索引、按名称和按取值。

按索引子集行与列

一种方法是按数据集的索引来对子集行与列。这就像把行和列描述为“第一行”“第二和第五列的所有行”或“第二到第五列的第一行”。我们用 R 中名为 iris 的数据集来说明这些说法。根据其文档,"这份著名的(Fisher 或 Anderson 的)鸢尾花数据集分别给出了三种鸢尾花各 50 朵样本的萼片长度与宽度、花瓣长度与宽度(单位:厘米)。物种为 Iris setosa、versicolor 和 virginica。"

# "The first row": iris[1, ] # "All rows in second and fifth columns": iris[, c(2, 5)] # "The first row in second to fifth columns": iris[1, 2:5]

要对子集数据,在数据集对象后使用方括号。方括号内第一个元素指定行,第二个元素指定列,两者之间用逗号分隔:

data[rows, columns]

按名称子集行与列

在 R 中,数据集的行和列都有名称属性。行名很少使用,默认提供索引——从 1 到数据集行数的整数——就像上一节所见。事实上,如果对 iris 调用 rownames(),您会发现它们只是从 1 到 150 的索引:

 > rownames(iris)
[1] "1"   "2"   "3"   "4"   "5"   "6"   "7"   "8"   "9"   "10"  "11"  "12"  "13"  "14"
[15] "15"  "16"  "17"  "18"  "19"  "20"  "21"  "22"  "23"  "24"  "25"  "26"  "27"  "28"
[29] "29"  "30"  "31"  "32"  "33"  "34"  "35"  "36"  "37"  "38"  "39"  "40"  "41"  "42"
[43] "43"  "44"  "45"  "46"  "47"  "48"  "49"  "50"  "51"  "52"  "53"  "54"  "55"  "56"
[57] "57"  "58"  "59"  "60"  "61"  "62"  "63"  "64"  "65"  "66"  "67"  "68"  "69"  "70"
[71] "71"  "72"  "73"  "74"  "75"  "76"  "77"  "78"  "79"  "80"  "81"  "82"  "83"  "84"
[85] "85"  "86"  "87"  "88"  "89"  "90"  "91"  "92"  "93"  "94"  "95"  "96"  "97"  "98"
[99] "99"  "100" "101" "102" "103" "104" "105" "106" "107" "108" "109" "110" "111" "112"
[113] "113" "114" "115" "116" "117" "118" "119" "120" "121" "122" "123" "124" "125" "126"
[127] "127" "128" "129" "130" "131" "132" "133" "134" "135" "136" "137" "138" "139" "140"
[141] "141" "142" "143" "144" "145" "146" "147" "148" "149" "150"

> nrow(iris)
[1] 150

行名在较小的数据集中更常见,用于使数据集中的观测易于辨认。例如,对于一个包含某位医生病人健康信息的小型数据集,其行名可以是病人的全名。

另一方面,列名几乎在任何数据集中都存在。您可以使用 colnames() 或 names() 函数获取它们:

colnames(iris)
[1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"     

names(iris)
[1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"

要按行和列的名称对子集数据集,只需再次使用方括号,前面加上数据集对象:

# 第五条观测的萼片宽度 iris["5", "Sepal.Width"] # 萼片宽度与花瓣宽度 iris[, c("Sepal.Width", "Petal.Width")]

需要注意的是,行名和列名都是字符,因此必须使用单引号或双引号!

按取值子集行与列

按取值对子集行与列往往最灵活。比如,您可以用如下条件语句提取 Iris setosa 的数据:

> iris[iris$Species == "setosa", ]
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           5.1         3.5          1.4         0.2  setosa
2           4.9         3.0          1.4         0.2  setosa
3           4.7         3.2          1.3         0.2  setosa
4           4.6         3.1          1.5         0.2  setosa

...

47          5.1         3.8          1.6         0.2  setosa
48          4.6         3.2          1.4         0.2  setosa
49          5.3         3.7          1.5         0.2  setosa
50          5.0         3.3          1.4         0.2  setosa

像 iris$Species == "setosa" 这样的条件语句应放在方括号中的行元素位置(即逗号前的第一个元素)。除了在第一个元素中使用条件语句外,您还可以在第二个元素中按索引或名称指定列。请在下面的控制台中试着只选出 Iris setosa 的萼片测量值:

# 打印 setosa 的萼片测量值 # 打印 setosa 的萼片测量值(按名称) iris[iris$Species == "setosa", c("Sepal.Length", "Sepal.Width")] # 打印 setosa 的萼片测量值(按索引) iris[iris$Species == "setosa", 1:2] test_or( test_output_contains('iris[iris$Species == "setosa", c("Sepal.Length", "Sepal.Width")]', incorrect_msg = "Select just the Sepal.Length and Sepal.Width columns for the setosa iris either by name or index."), test_output_contains('iris[iris$Species == "setosa", c("Sepal.Width", "Sepal.Length")]', incorrect_msg = "Select just the Sepal.Length and Sepal.Width columns for the setosa iris either by name or index.")) success_msg("Great work!")

回顾

在本教程中,您:

  • 学习了按索引对子集数据框。行和列分别从 1 到相应的数量进行整数索引。
  • 学习了按名称对子集数据框。您了解到行名很少单独设置,而列名是字符类型。
  • 学习了在方括号的行元素中使用条件语句,按取值对子集数据框。
  • 学习了结合这些方法以实现更灵活的子集化(例如,对行使用条件,对列按索引或名称子集)。

下面是一些练习,帮助巩固您所学的内容。熟能生巧,动手试试吧!

练习题

选出所有萼片宽度大于花瓣长度的观测。

# 哪些观测的萼片宽度大于花瓣长度? # 哪些观测的萼片宽度大于花瓣长度? iris[iris$Sepal.Width > iris$Petal.Length, ] test_output_contains('iris[iris$Sepal.Width > iris$Petal.Length, ]', incorrect_msg = paste("Select the observations for which Sepal.Width values", "are larger than Petal.Length values.")) success_msg("Nice! Turns out only Iris setosa have this shape.")
在方括号内使用 iris$Sepal.Width > iris$Petal.Length。别忘了逗号!

选出所有 Iris versicolor 中,萼片宽度大于所有物种平均萼片宽度的观测。

# 将 versicolor 数据存为名为 versicolor 的对象 # 选出所有萼片宽度高于平均值的 Iris versicolor # 将 versicolor 数据存为名为 versicolor 的对象 versicolor <- iris[iris$Species == "versicolor", ] # 选出所有萼片宽度高于平均值的 Iris versicolor versicolor[versicolor$Sepal.Width > mean(iris$Sepal.Width), ] test_object('versicolor', undefined_msg = "Did you define the versicolor object?", incorrect_msg = paste("Select where Species is equal to \"versicolor\".", "Remember to use the == operator!")) test_output_contains('versicolor[versicolor$Sepal.Width > mean(iris$Sepal.Width), ]', incorrect_msg = paste("Not quite! Are you using the mean() function", "to find the average sepal width across all species", "and not just for Iris versicolor?")) success_msg("Great work!")
使用 mean() 函数计算 iris 中的平均萼片宽度,然后以 versicolor 为前缀写条件语句,只选出高于平均值的观测。

报告所有花瓣长度小于 5 厘米的 Iris virginica 的平均萼片宽度。

# 您可以用任何您喜欢的方法来解决! # 将 virginica 数据存为名为 virginica 的对象 virginica <- iris[iris$Species == "virginica", ] # 花瓣长度小于 5 的 Iris virginica 的平均萼片宽度 mean(virginica[virginica$Petal.Length < 5, ]$Sepal.Width) test_output_contains('2.8', incorrect_msg = "Incorrect! This is a tough one!") success_msg("Excellent!")
首先尝试对子集出所有 Iris virginica,然后筛选 Petal.Length 小于 5 的观测。调用 mean() 函数即可求平均值。

想进一步了解从数据中提取洞见的其他方法?请查看 DataCamp 上这些课程!

看看我们的 在 R 中合并数据集 教程。

主题
R
数据科学

进一步学习 R

课程

使用 dplyr 进行数据处理

4 小时
175.8K
通过学习如何使用 dplyr 转换和处理数据,提升 Tidyverse 技能。
查看详情开始课程

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续
继续操作即表示您接受我们的《使用条款》和《隐私政策》,并同意您的数据存储在美国。
查看更多