R语言初级教程(19): 数据框(上篇)
由于数据框的内容比较多,因此将用三篇文章来介绍,这是第一篇。
数据框(dataframe)是R中最常处理的数据结构。数据框由行、列构成,结构有点像矩阵,见下图:

数据框的每一行是一个观测数据(或实例或样本),每列包含一个变量(或特征或属性)数值。矩阵中的值只能是数字,但数据框中的值可以是数字,也可以是文本(例如:性别变量中的male
或female
),也可以是日期(例如:2020/02/02
),也可以是逻辑变量(TRUE
或FALSE
)。
上图是一个数据框形式的电子表格(对20块田地的描述),其中包含七个变量。其中数值型变量为:面积(Area
),坡度(Slope
),土壤PH值(Soil.pH
)和蠕虫密度(Worm.density
);类别变量为:田地名(Field.Name
)和植被类型(Vegetation
);逻辑变量为:是否潮湿(Damp
),值为TRUE
或FALSE
。另外,最左边是行名,最上面是列名。
处理数据框的时候,有两点要记住:
-
虽然各列允许有不同类型:数值型向量、因子、字符型向量、日期时间向量等,但同一列的数据类型一定是相同的。
-
列名中不允许有空格出现,否则
read.table()
将读取失败。因此上面的变量名Field Name
,Soil pH
,Worm density
中的空格会用.
来代替。
上述的表格保存在worms.txt
文件中,如下图:

我们用R中read.table()
函数来读取这个文件:
> worms <- read.table("c:\\data\\worms.txt",header=T)
一旦文件被导入到R中,我们通常会做以下四件事:
-
使用
attach
使变量可以在R会话中按名称访问 -
使用
names
获取变量名称列表 -
使用
head
查看数据的前几行 -
使用
tail
来查看数据的最后几行
> attach(worms)
> names(worms)
[1] "Field.Name" "Area" "Slope" "Vegetation" "Soil.pH"
[6] "Damp" "Worm.density"
> head(worms)
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
> tail(worms)
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
19 Gravel.Pit 2.9 1 Grassland 3.5 FALSE 1
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
要查看整个数据框的内容,只需键入其名称:
> worms
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
7 Church.Field 3.5 3 Grassland 4.2 FALSE 3
8 Ashurst 2.1 0 Arable 4.8 FALSE 4
9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
12 North.Gravel 3.3 1 Grassland 4.1 FALSE 1
13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
19 Gravel.Pit 2.9 1 Grassland 3.5 FALSE 1
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
注意,R已将我们的缩写T
和F
扩展为TRUE
和FALSE
。 现在,worms
变量具有数据框的所有属性。 例如,您可以使用summary
对其进行总结:
> summary(worms)
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
Ashurst : 1 Min. :0.800 Min. : 0.00 Arable :3 Min. :3.500 Mode :logical Min. :0.00
Cheapside : 1 1st Qu.:2.175 1st Qu.: 0.75 Grassland:9 1st Qu.:4.100 FALSE:14 1st Qu.:2.00
Church.Field: 1 Median :3.000 Median : 2.00 Meadow :3 Median :4.600 TRUE :6 Median :4.00
Farm.Wood : 1 Mean :2.990 Mean : 3.50 Orchard :1 Mean :4.555 Mean :4.35
Garden.Wood : 1 3rd Qu.:3.725 3rd Qu.: 5.25 Scrub :4 3rd Qu.:5.000 3rd Qu.:6.25
Gravel.Pit : 1 Max. :5.100 Max. :11.00 Max. :5.700 Max. :9.00
(Other) :14
从上面的运行结果可以看出,连续变量用六个量来归纳:最小值(Min.
)、第一个四分位数(1st Qu.
)、中位数(Median
)、平均值(Mean
)、第三个四分位数(3rd Qu.
)、最大值(Max.
)。 对于类别变量和逻辑变量,将算出每类的个数。注意:类别变量Field.Name
的每一行都不一样,由于R最多可以列出6
个,因此其它14
个用(Other)
代替。
接下来,将详细介绍如何用R处理数据框。
1. 下标和索引
我们还是用worms
数据框为例:
> worms <- read.table("c:\\data\\worms.txt", header=T)
> worms
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
7 Church.Field 3.5 3 Grassland 4.2 FALSE 3
8 Ashurst 2.1 0 Arable 4.8 FALSE 4
9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
12 North.Gravel 3.3 1 Grassland 4.1 FALSE 1
13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
19 Gravel.Pit 2.9 1 Grassland 3.5 FALSE 1
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
高效处理数据框的关键在于能够轻松地使用下标(有些人称之为索引)。在R中,下标出现在方括号[]
中。dataframe
是一个二维对象,由行和列组成。行由第一个(左)下标引用,列由第二个(右)下标引用。因此
> worms[3, 5]
[1] 4.3
是Soil.pH
(第5
列变量)的第3
行值。 要从Worm.density
(第7
列变量)提取一系列值(例如第14
至19
行),我们可以使用冒号运算符:
生成一系列下标(14
、15
、16
、17
、18
和19
):
> worms[14:19, 7]
[1] 0 6 8 4 5 1
如果要提取一组行和一组列,需要为行和列下标生成一系列下标。 假设我们要从第1
行到第5
行使用Area
和Slope
(第2
列和第3
列):
> worms[1:5, 2:3]
Area Slope
1 3.6 11
2 5.1 2
3 2.8 3
4 2.4 5
5 3.8 0
接下来的一点非常重要,不经常实践很难掌握。 要选择一行中的所有条目,语法为“数字逗号为空白”(例如[2, ]
)。 同样,要选择列中的所有条目,语法为“空白逗号数字”(例如[ ,2]
)。 因此,要选择第3
行中的所有列,我们输入
> worms[3, ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
而要选择第3
列中的所有行,我们需要
> worms[ ,3]
[1] 11 2 3 5 0 2 3 0 0 4 10 1 2 6 0 0 8 2 1 10
这是R的一项重要功能,并且会给初学者带来麻烦。 请注意,这两个看似相似的命令创建了不同类型的对象:
> class(worms[3, ])
[1] "data.frame"
> class(worms[ ,3])
[1] "integer"
您可以提取多行或多列。 例如,使用连接函数c()
来创建所需的列号c(1, 5)
来提取Field.Name
和Soil.pH
(第1
列和第5
列)列:
> worms[ ,c(1, 5)]
Field.Name Soil.pH
1 Nashs.Field 4.1
2 Silwood.Bottom 5.2
3 Nursery.Field 4.3
4 Rush.Meadow 4.9
5 Gunness.Thicket 4.2
6 Oak.Mead 3.9
7 Church.Field 4.2
8 Ashurst 4.8
9 The.Orchard 5.7
10 Rookery.Slope 5.0
11 Garden.Wood 5.2
12 North.Gravel 4.1
13 South.Gravel 4.0
14 Observatory.Ridge 3.8
15 Pond.Field 5.0
16 Water.Meadow 4.9
17 Cheapside 4.7
18 Pound.Hill 4.5
19 Gravel.Pit 3.5
20 Farm.Wood 5.1
2. 随机选择行
在Bootstraping(自助法,一种有放回采样方法)或cross-validation(交叉验证)中,我们可能希望从数据框中随机选择某些行。 我们使用sample()
函数来执行此操作:默认的replace = FALSE
表示不放回抽样,会随机打乱行顺序,而选项replace = TRUE
表示有放回抽样,则允许某些行有多个副本,而忽略其他行 。 来看下这两者的区别:
## 不放回抽样,无重复行
> worms[sample(1:20, 10), ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
7 Church.Field 3.5 3 Grassland 4.2 FALSE 3
6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
8 Ashurst 2.1 0 Arable 4.8 FALSE 4
13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
## 放回抽样,可能存在重复行
> worms[sample(1:20, 10, replace=T), ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
9.1 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
15.1 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
8 Ashurst 2.1 0 Arable 4.8 FALSE 4
请注意,上面结果的行号是由sample()
函数给出的随机序列(未排序),因此,如果要排序的随机样本,则需要在随机化之后对数据框进行排序。
3. 排序
常见的是按行对数据框进行排序,而很少按列进行排序。 因为我们要按行(第一个下标)进行排序,所以我们需在逗号前指定行下标的顺序。 因此,为了根据其中一列中的值(例如Slope
)对数据框进行排序,我们有:
> worms[order(Slope), ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
8 Ashurst 2.1 0 Arable 4.8 FALSE 4
9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
12 North.Gravel 3.3 1 Grassland 4.1 FALSE 1
19 Gravel.Pit 2.9 1 Grassland 3.5 FALSE 1
2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
7 Church.Field 3.5 3 Grassland 4.2 FALSE 3
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
这里有一些注意事项。 由于我们希望将排序应用于所有列,因此列下标(逗号后)为空白:[order(Slope), ]
。 原始行号保留在最左边。 当排序变量的值相同时(例如Slope = 0
有5
个地方),则各行按其原始顺序(5 8 9 15 16
)排列。 如果您希望数据框以相反的顺序(降序),则可以在order()
函数之外使用rev()
函数,如下所示:
> worms[rev(order(Slope)), ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
7 Church.Field 3.5 3 Grassland 4.2 FALSE 3
3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
19 Gravel.Pit 2.9 1 Grassland 3.5 FALSE 1
12 North.Gravel 3.3 1 Grassland 4.1 FALSE 1
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
8 Ashurst 2.1 0 Arable 4.8 FALSE 4
5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
现在请注意,如果排序变量的值相同时(例如Slope = 0
),则原始行的顺序也相反(16 15 9 8 5
)。
其实也可以不使用rev()
函数来实现降序,直接通过设置order()
函数中的decreasing
参数为TRUE
来实现,如下所示:
> worms[order(Slope, decreasing=T), ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
7 Church.Field 3.5 3 Grassland 4.2 FALSE 3
2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
12 North.Gravel 3.3 1 Grassland 4.1 FALSE 1
19 Gravel.Pit 2.9 1 Grassland 3.5 FALSE 1
5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
8 Ashurst 2.1 0 Arable 4.8 FALSE 4
9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
对于这种情况,如果排序变量的值相同时(例如Slope = 0
),还是保持原始行的顺序(5 8 9 15 16
)。
更复杂的排序操作可能涉及两个或多个变量。这可以通过在order()
函数中使用逗号分隔一系列变量名来实现。R将根据左边的变量排序,而当第一个变量的值相同时接着按第二个变量排序,依此类推。假设我们要按每种植被类型(Vegetation
)中的蠕虫密度(Worm.density
)对数据框的行进行排序:
> worms[order(Vegetation, Worm.density), ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
8 Ashurst 2.1 0 Arable 4.8 FALSE 4
18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
12 North.Gravel 3.3 1 Grassland 4.1 FALSE 1
19 Gravel.Pit 2.9 1 Grassland 3.5 FALSE 1
3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
7 Church.Field 3.5 3 Grassland 4.2 FALSE 3
1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
请注意,与单条件排序一样,当值一样时(例如Vegetation=Grassland, Worm.density=2
),行仍按其原始顺序排列(3 6 13
)。 我们可能想通过指定第三种排序条件(例如土壤pH值)来覆盖此设置:
> worms[order(Vegetation,Worm.density,Soil.pH), ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
8 Ashurst 2.1 0 Arable 4.8 FALSE 4
18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
14 Observatory.Ridge 1.8 6 Grassland 3.8 FALSE 0
19 Gravel.Pit 2.9 1 Grassland 3.5 FALSE 1
12 North.Gravel 3.3 1 Grassland 4.1 FALSE 1
6 Oak.Mead 3.1 2 Grassland 3.9 FALSE 2
13 South.Gravel 3.7 2 Grassland 4.0 FALSE 2
3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
7 Church.Field 3.5 3 Grassland 4.2 FALSE 3
1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
规则是这样的:如果不确定,使用比您认为需要的更多的变量排序。这样你就可以保证这些行是按照你期望的顺序排列的。
也许您只想要排序后的数据流中的某些列?假设我们想要植被,蠕虫密度,土壤pH值和坡度这四列,而且顺序从左到右。实现如下:
> worms[order(Vegetation,Worm.density), c(4,7,5,3)]
Vegetation Worm.density Soil.pH Slope
8 Arable 4 4.8 0
18 Arable 5 4.5 2
2 Arable 7 5.2 2
14 Grassland 0 3.8 6
12 Grassland 1 4.1 1
19 Grassland 1 3.5 1
3 Grassland 2 4.3 3
6 Grassland 2 3.9 2
13 Grassland 2 4.0 2
7 Grassland 3 4.2 3
1 Grassland 4 4.1 11
10 Grassland 7 5.0 4
4 Meadow 5 4.9 5
15 Meadow 6 5.0 0
16 Meadow 8 4.9 0
9 Orchard 9 5.7 0
20 Scrub 3 5.1 10
17 Scrub 4 4.7 8
5 Scrub 6 4.2 0
11 Scrub 8 5.2 10
您也可以根据列的名称来选择列,但是输入起来比较麻烦,因为您需要将变量名放在引号中,像这样:
> worms[order(Vegetation,Worm.density), c("Vegetation", "Worm.density", "Soil.pH", "Slope")]
Vegetation Worm.density Soil.pH Slope
8 Arable 4 4.8 0
18 Arable 5 4.5 2
2 Arable 7 5.2 2
14 Grassland 0 3.8 6
12 Grassland 1 4.1 1
19 Grassland 1 3.5 1
3 Grassland 2 4.3 3
6 Grassland 2 3.9 2
13 Grassland 2 4.0 2
7 Grassland 3 4.2 3
1 Grassland 4 4.1 11
10 Grassland 7 5.0 4
4 Meadow 5 4.9 5
15 Meadow 6 5.0 0
16 Meadow 8 4.9 0
9 Orchard 9 5.7 0
20 Scrub 3 5.1 10
17 Scrub 4 4.7 8
5 Scrub 6 4.2 0
11 Scrub 8 5.2 10
4. 使用逻辑条件选择行
一种常见的操作是根据一个或多个变量(数据框的列)中的值从数据框中选择某些行。假设我们希望将数据限制为田地是潮湿的情况(即Damp=TRUE
)。且我们需要所有列,因此下标的语法为[“哪些行”, 空白]
:
> worms[Damp == T, ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
请注意,由于Damp
是一个逻辑变量(只有两个可能的值:TRUE
或FALSE
),我们可以用缩写形式T
或F
来引用TRUE
或FALSE
。还要注意,在这种情况下T
不用引号来引起:T
表示真,而不是字符"T"
。 另一个要点是,逻辑条件的符号是==
(两个连续的等号,它们之间是没有空格的)。
选择行的逻辑可以引用不止一列中的值(或值的函数)。 假设我们需要蠕虫密度高于中位数(>median(Worm.density)
)且土壤pH值小于5.2
的田地数据。 在R中,与
的逻辑运算符是&
:
> worms[Worm.density > median(Worm.density) & Soil.pH < 5.2, ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
假设我们想从数据框中提取所有包含数字(而不是字符或逻辑变量)的列。 可以使用sapply
函数将is.numeric
函数应用于worms
的所有列,来创建适当的下标,如下所示:
> worms[ ,sapply(worms, is.numeric)]
Area Slope Soil.pH Worm.density
1 3.6 11 4.1 4
2 5.1 2 5.2 7
3 2.8 3 4.3 2
4 2.4 5 4.9 5
5 3.8 0 4.2 6
6 3.1 2 3.9 2
7 3.5 3 4.2 3
8 2.1 0 4.8 4
9 1.9 0 5.7 9
10 1.5 4 5.0 7
11 2.9 10 5.2 8
12 3.3 1 4.1 1
13 3.7 2 4.0 2
14 1.8 6 3.8 0
15 4.1 0 5.0 6
16 3.9 0 4.9 8
17 2.2 8 4.7 4
18 4.4 2 4.5 5
19 2.9 1 3.5 1
20 0.8 10 5.1 3
提取变量是因子的列:
> worms[ ,sapply(worms,is.factor)]
Field.Name Vegetation
1 Nashs.Field Grassland
2 Silwood.Bottom Arable
3 Nursery.Field Grassland
4 Rush.Meadow Meadow
5 Gunness.Thicket Scrub
6 Oak.Mead Grassland
7 Church.Field Grassland
8 Ashurst Arable
9 The.Orchard Orchard
10 Rookery.Slope Grassland
11 Garden.Wood Scrub
12 North.Gravel Grassland
13 South.Gravel Grassland
14 Observatory.Ridge Grassland
15 Pond.Field Meadow
16 Water.Meadow Meadow
17 Cheapside Scrub
18 Pound.Hill Arable
19 Gravel.Pit Grassland
20 Farm.Wood Scrub
由于worms
是数据框,默认情况下所有字符串将强制变为因子,因此worms[ ,sapply(worms,is.character)]
将输出NULL
:
> worms[ ,sapply(worms,is.character)]
NULL
要从数据框中删除一行或多行,请使用负下标。 因此,删除中间10
行(即行号从6
到15
)可以这样做:
> worms[-(6:15), ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
1 Nashs.Field 3.6 11 Grassland 4.1 FALSE 4
2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
3 Nursery.Field 2.8 3 Grassland 4.3 FALSE 2
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
19 Gravel.Pit 2.9 1 Grassland 3.5 FALSE 1
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
这是非Grassland
的所有行(请记住,逻辑符号!
表示非
):
> worms[!(Vegetation=="Grassland"), ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
2 Silwood.Bottom 5.1 2 Arable 5.2 FALSE 7
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
5 Gunness.Thicket 3.8 0 Scrub 4.2 FALSE 6
8 Ashurst 2.1 0 Arable 4.8 FALSE 4
9 The.Orchard 1.9 0 Orchard 5.7 FALSE 9
11 Garden.Wood 2.9 10 Scrub 5.2 FALSE 8
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
18 Pound.Hill 4.4 2 Arable 4.5 FALSE 5
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
如果想使用减号-
而不是逻辑非!
从数据框中删除行,则使用的表达式计算结果必须为数字。which()
函数对此很有用。 让我们使用此技术来删除非潮湿田地的数据:
> worms[-which(Damp==F), ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
也可以用更优雅的方式来实现:
> worms[!Damp==F, ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
> worms[Damp==T, ]
Field.Name Area Slope Vegetation Soil.pH Damp Worm.density
4 Rush.Meadow 2.4 5 Meadow 4.9 TRUE 5
10 Rookery.Slope 1.5 4 Grassland 5.0 TRUE 7
15 Pond.Field 4.1 0 Meadow 5.0 TRUE 6
16 Water.Meadow 3.9 0 Meadow 4.9 TRUE 8
17 Cheapside 2.2 8 Scrub 4.7 TRUE 4
20 Farm.Wood 0.8 10 Scrub 5.1 TRUE 3
今天的内容就到此为止,介绍了什么是数据框以及对数据框的一些处理,下一篇文章将继续介绍有关数据框的处理。
感谢您的阅读!想了解更多有关技巧,请关注我的微信公众号“R语言和Python学堂”,我将定期更新相关文章。
