课程
无论您是在比较不同人群对营销活动的反应、聚焦某个特定时间段,还是从库存中提取少数几种产品的信息,给数据集做子集都能帮助您从数据中提取有用的观察。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!")
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!")
Petal.Length 小于 5 的观测。调用 mean() 函数即可求平均值。想进一步了解从数据中提取洞见的其他方法?请查看 DataCamp 上这些课程!
看看我们的 在 R 中合并数据集 教程。