R数据框实用操作方法总结

一、开场

R语言中的数据框data.frame被定义为由不同变量值(列)和不同观察值(行)所组成的二维数据结构,每一列存储的数据类型必须相同,不同数据列的数据类型可以相同,也可以不同,但是每列的行数(长度)必须相同。其实R数据框就是标准的Excel表格数据,对,你可以这样理解……

数据框是R语言进行数据处理和分析常用的数据结构类型,这也为什么R的内置数据集有占46%的是数据框。通常用R基础函数read.table()读取的excel表格数据,在R中存储为数据框data.frame或者列表list。

数据框的特征很有意思,关于数据框实用方法有很多,都是为解决现实实际问题而发展出来的方法,关于R数据框的知识和使用方法书上的案例比较呆板老旧,网上的一般资源又比较零散和随意,往往你查到的不是你想要的。

我现在集中精力帮助大家整理出一个实用的、有效的、可以当速查救命手册的帮助文档来!接下来一系列简书日更将主要对数据框进行总结和分享,希望能帮到大家!对我也是一次比较重要的R知识的整理、归纳、总结和提升。

当你参透R数据框的时候,其实你的R语言已经达到一定的水平了……

 


目录

一、开场

1.数据框的定义

2.我的初衷

二、数据框实用操作方法

1.创建数据框的几种方法

2.数据框的大小和维度查看

3.数据框的行和列查看及操作

4.数据框的元素操作问题

5.数据框的排序问题

6.数据框的分离与合并问题

7.数据框的转置问题

8.数据框的删除、增加和替换问题


二、数据框实用操作方法

### 1.创建数据框的几种方法

#### 1.1 data.frame()创建

df <- data.frame(编号 = 1:10, 姓名 = c("王明", "李磊", "张乐", "刘能", "黄粲", "赵月", "朱忻", "陈振", "武琳", "孙晔"), 性别 = c("男", "男", "男", "男", "女", "女", "女", "男", "女", "女"), 数学成绩 = c("90", "88", "80", "70", "95", "91", "90", "81", "80", "76"), 语文成绩 = c("91", "75", "83", "89", "90", "91", "88", "77", "85", "90"))

#@ 查看df内容

df

#    编号 姓名 性别 数学成绩 语文成绩

# 1    1 王明  男      90      91

# 2    2 李磊  男      88      75

# 3    3 张乐  男      80      83

# 4    4 刘能  男      70      89

# 5    5 黄粲  女      95      90

# 6    6 赵月  女      91      91

# 7    7 朱忻  女      90      88

# 8    8 陈振  男      81      77

# 9    9 武琳  女      80      85

# 10  10 孙晔  女      76      90

class(df)

# [1] "data.frame"

#### 1.2 as.data.frame()强制转换其他数据结构为数据框

#@ 转换矩阵matrix为数据框data.frame:as.data.frame(matrix)

data(volcano) # 载入内置数据集volcano

class(volcano)

# [1] "matrix"

df1 <- as.data.frame(volcano)

class(df1)

# [1] "data.frame"

#@ 转换列表list为数据框data.frame:as.data.frame(list)

library(datasets)

data(state)

class(state.center) # 查看state.center的数据结构类型

# [1] "list"

df2 <- as.data.frame(state.center)

head(df2)

# x      y

# 1  -86.7509 32.5901

# 2 -127.2500 49.2500

# 3 -111.6250 34.2192

# 4  -92.2992 34.7336

# 5 -119.7730 36.5341

# 6 -105.5130 38.6777

class(df2)

# [1] "data.frame"

#@ 转换数组array为数据框data.frame

data(iris3) # 载入内置数据集

class(iris3)

# [1] "array"

head(iris3)

# [1] 5.1 4.9 4.7 4.6 5.0 5.4

df3 <- as.data.frame(iris3)

class(df3)

# [1] "data.frame"

head(df3)

# Sepal L..Setosa Sepal W..Setosa Petal L..Setosa

# 1            5.1            3.5            1.4

# 2            4.9            3.0            1.4

# 3            4.7            3.2            1.3

# 4            4.6            3.1            1.5

# 5            5.0            3.6            1.4

# 6            5.4            3.9            1.7

# Petal W..Setosa Sepal L..Versicolor Sepal W..Versicolor

# 1            0.2                7.0                3.2

# 2            0.2                6.4                3.2

# 3            0.2                6.9                3.1

# 4            0.2                5.5                2.3

# 5            0.2                6.5                2.8

# 6            0.4                5.7                2.8

# Petal L..Versicolor Petal W..Versicolor Sepal L..Virginica

# 1                4.7                1.4                6.3

# 2                4.5                1.5                5.8

# 3                4.9                1.5                7.1

# 4                4.0                1.3                6.3

# 5                4.6                1.5                6.5

# 6                4.5                1.3                7.6

# Sepal W..Virginica Petal L..Virginica Petal W..Virginica

# 1                3.3                6.0                2.5

# 2                2.7                5.1                1.9

# 3                3.0                5.9                2.1

# 4                2.9                5.6                1.8

# 5                3.0                5.8                2.2

# 6                3.0                6.6                2.1

#@ 以上转换在条件满足的时候是可以相互强制转换的,例如:可以矩阵到数据框,也可以数据框到矩阵。

#### 1.3 R函数读取数据文件,存为数据框对象

#@ 为了大家测试方便,我们先用R内置函数write.csv保存R一个内置数据框数据集到本地:mtcars,然后再读取这个表格文件:mtcars.csv,用下面三种方法读取。这个文件默认保存到你的工作目录中,查看你的工作目录的方法是getwd(),也可以直接用函数dir()查看,如果你设置了自己的工作路径,那这个文件就在你的当前工作路径内

data("mtcars")

dim(mtcars)

# [1] 32 11

class(mtcars)

# [1] "data.frame"

write.csv(mtcars, file = "mtcars.csv")

dir()

# [1] "mtcars.csv"                   

# [2] "R数据框实用操作方法大总结.docx"

# [3] "简书日更挑战_20191222_Sunday.R"

#@ 我的已经保存到本地电脑文件夹中了(当前工作目录)

getwd()

# [1] "E:/学习空间/博客/简书/简书日更挑战/2019年/12月/20191222_Sunday"

#@ 现在我们用函数读取数据文件

#@ read.table(),R基础函数

df4 <- read.table("mtcars.csv", sep = ",", header = T)

dim(df4)

# [1] 32 11

class(df4)

# [1] "data.frame"

#@ read.xlsx(),R扩增包openxlsx函数,使用这个函数之前你需要安装这个包:openxlsx,如果已经安装就OK,没有的话执行安装代码:install.packages("openxlsx"),安装成功之后就可以往下走了,然后手动操作一下,用Excel软件打开我们刚才保存的mtcars.csv文件,然后另存为xlsx文件,文件格式变为.xlsx,文件名不变,还是mtcars,然后关闭文件,执行dir()

dir()

# [1] "mtcars.csv"                   

# [2] "mtcars.xlsx"                 

# [3] "R数据框实用操作方法大总结.docx"

# [4] "简书日更挑战_20191222_Sunday.R"

#@ 我们看到多出一个mtcars.xlsx文件

df5 <- openxlsx::read.xlsx("mtcars.xlsx", sheet = 1, startRow = 1, colNames = T, rowNames = T, detectDates = FALSE)

dim(df5)

# [1] 32 11

class(df5)

# [1] "data.frame"

#@ import(),R扩增包rio函数import(),同样这个是扩增包,使用前需要安装rio包,安装完成之后就可以继续往下走了

df6 <- rio::import("mtcars.csv", sep = ",")

df7 <- rio::import("mtcars.xlsx")

#@ 神包rio就这个牛,这只是小试牛刀,它可以支持32种格式文件的读和写

#@ 使用SQL查询Data Frame对象或者数据库文件,sqldf包,同样使用前需要安装它

library(sqldf)

# 载入需要的程辑包:gsubfn

# 载入需要的程辑包:proto

# 载入需要的程辑包:RSQLite

library(chron) # 同样使用前需要安装

DF <- read.table(textConnection(Lines), skip = 1,  as.is = TRUE, col.names = c("Id", "Date", "Time", "Quality", "Lat", "Long"))

DF

# Id      Date  Time Quality    Lat    Long

# 1 STM05-1 28/02/2005 17:35    Good -35.562 177.158

# 2 STM05-1 28/02/2005 19:44    Good -35.487 177.129

# 3 STM05-1 28/02/2005 23:01 Unknown -35.399 177.064

# 4 STM05-1 01/03/2005 07:28 Unknown -34.978 177.268

# 5 STM05-1 01/03/2005 18:06    Poor -34.799 177.027

# 6 STM05-1 01/03/2005 18:47    Poor -34.850 177.059

# 7 STM05-2 28/02/2005 12:49    Good -35.928 177.328

# 8 STM05-2 28/02/2005 21:23    Poor -35.926 177.314

dim(DF)

# [1] 8 6

class(DF)

# [1] "data.frame"

str(DF)

# 'data.frame': 8 obs. of  6 variables:

#  $ Id    : chr  "STM05-1" "STM05-1" "STM05-1" "STM05-1" ...

# $ Date  : chr  "28/02/2005" "28/02/2005" "28/02/2005" "01/03/2005" ...

# $ Time  : chr  "17:35" "19:44" "23:01" "07:28" ...

# $ Quality: chr  "Good" "Good" "Unknown" "Unknown" ...

# $ Lat    : num  -35.6 -35.5 -35.4 -35 -34.8 ...

# $ Long  : num  177 177 177 177 177 ...

#@ 用transform()对数据框对象进行操作,为原数据框添加新的列,改变原变量列的值,通过赋值NULL删除列变量

DF2 <- transform(DF, Date = chron(Date, format = "d/m/y"), Time = times(paste(Time, "00", sep = ":")), Quality = factor(Quality, levels = c("Good", "Poor", "Unknown")))

dim(DF2)

# [1] 8 6

class(DF2)

# [1] "data.frame"

#@ 用sqldf函数获取R内置数据集

data("mtcars")

DF3 <-sqldf("select am,hp,mpg from mtcars where cyl='4' and wt<3")

DF3

# am  hp  mpg

# 1  1  93 22.8

# 2  1  66 32.4

# 3  1  52 30.4

# 4  1  65 33.9

# 5  0  97 21.5

# 6  1  66 27.3

# 7  1  91 26.0

# 8  1 113 30.4

# 9  1 109 21.4

class(DF3)

# [1] "data.frame"

#@ R就是这么强大!

### 2.数据框的大小及维度查看

#@ dim()查看数据维度

dim(df) # 我们利用函数data.frame手动创建了一个10行、5列的数据框,即10个观察值:"1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10",5个变量值:"编号"    "姓名"    "性别"    "数学成绩" "语文成绩"

# [1] 10  5

#@ attributes() 获取对象属性列表,记住不只是数据集的,也可以是R中的一切对象,对于R来说一切都是对象,正如对于Linux一切都是文件

attributes(df)

# $names

# [1] "编号"    "姓名"    "性别"    "数学成绩" "语文成绩"

#

# $class

# [1] "data.frame"

#

# $row.names

# [1]  1  2  3  4  5  6  7  8  9 10

#@ str() 显示任意R对象的结构

str(df)

# 'data.frame': 10 obs. of  5 variables:

#  $ 编号    : int  1 2 3 4 5 6 7 8 9 10

# $ 姓名    : Factor w/ 10 levels "陈振","黄粲",..: 6 3 8 4 2 9 10 1 7 5

# $ 性别    : Factor w/ 2 levels "男","女": 1 1 1 1 2 2 2 1 2 2

# $ 数学成绩: Factor w/ 8 levels "70","76","80",..: 6 5 3 1 8 7 6 4 3 2

# $ 语文成绩: Factor w/ 8 levels "75","77","83",..: 8 1 3 6 7 8 5 2 4 7

 

### 3.数据框的行、列查看及操作

#### 3.1 数据框行查看及操作

df

# 编号 姓名 性别 数学成绩 语文成绩

# 1    1 王明  男      90      91

# 2    2 李磊  男      88      75

# 3    3 张乐  男      80      83

# 4    4 刘能  男      70      89

# 5    5 黄粲  女      95      90

# 6    6 赵月  女      91      91

# 7    7 朱忻  女      90      88

# 8    8 陈振  男      81      77

# 9    9 武琳  女      80      85

# 10  10 孙晔  女      76      90

rownames(df) # 查看df的行名

# [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10"

row.names(df)

# [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10"

NROW(df) # 统计有多少行

# [1] 10

row.names.data.frame(df) # 查看数据框的行名

# [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10"

#@ 对行数据进行求平均值rowMeans()

dim(df1)

# [1] 87 61

df1[1:5,1:5]

# V1  V2  V3  V4  V5

# 1 100 100 101 101 101

# 2 101 101 102 102 102

# 3 102 102 103 103 103

# 4 103 103 104 104 104

# 5 104 104 105 105 105

df1_rowmean <- rowMeans(df1)

length(df1_rowmean)

# [1] 87

class(df1_rowmean)

# [1] "numeric"

#@ 对行数据进行求和rowSums()

df1_rowsum <- rowSums(df1)

length(df1_rowsum)

# [1] 87

class(df1_rowsum)

# [1] "numeric"

#### 3.2 数据框列查看及操作

colnames(df)

# [1] "编号"    "姓名"    "性别"    "数学成绩" "语文成绩"

#@ 对数据框列进行求平均colMeans()

df1_colmean <- colMeans(df1)

length(df1_colmean)

# [1] 61

class(df1_colmean)

# [1] "numeric"

#@ 对数据框列进行求和colSums()

df1_colsum <- colSums(df1)

length(df1_colsum)

# [1] 61

class(df1_colsum)

# [1] "numeric"

#### 3.3 其他的操作

#@ 当前你也可以对数据框整体或者行、列求其他的值:例如最小值、最大值、对数值、幂值、方差、标准差、MAD等等,前题是这个数据框是数值型的数据框,因为字符串无法参与计算

max(df)

# Error in FUN(X[[i]], ...) : 只适用于全数值数据框

max(df1)

# [1] 195

min(df1)

# [1] 94

df1_log2 <- log2(df1)

dim(df1_log2)

# [1] 87 61

df1[1:5,1:5]

#    V1  V2  V3  V4  V5

# 1 100 100 101 101 101

# 2 101 101 102 102 102

# 3 102 102 103 103 103

# 4 103 103 104 104 104

# 5 104 104 105 105 105

df1_log2[1:5,1:5]

#        V1      V2      V3      V4      V5

# 1 6.643856 6.643856 6.658211 6.658211 6.658211

# 2 6.658211 6.658211 6.672425 6.672425 6.672425

# 3 6.672425 6.672425 6.686501 6.686501 6.686501

# 4 6.686501 6.686501 6.700440 6.700440 6.700440

# 5 6.700440 6.700440 6.714246 6.714246 6.714246

df1_row1_log2 <- log2(df1[1,]) # 只对第一行进行log2转化

df1_row1_log2[1:5,1:5]

#            V1      V2      V3      V4      V5

# 1    6.643856 6.643856 6.658211 6.658211 6.658211

# NA        NA      NA      NA      NA      NA

# NA.1      NA      NA      NA      NA      NA

# NA.2      NA      NA      NA      NA      NA

# NA.3      NA      NA      NA      NA      NA

df1_col1_log2 <- log2(df1[,1]) # 只对第一列进行log2转化

head(df1_col1_log2)

# [1] 6.643856 6.658211 6.672425 6.686501 6.700440 6.714246

sum(df1) # 对数值型的数据框求和

# [1] 690907

#@ 其他的自己去测试,记住R可以计算一切数学计算,如果没有现成的工具就自己构建工具

### 4.数据框的元素操作问题

df

# 编号 姓名 性别 数学成绩 语文成绩

# 1    1 王明  男      90      91

# 2    2 李磊  男      88      75

# 3    3 张乐  男      80      83

# 4    4 刘能  男      70      89

# 5    5 黄粲  女      95      90

# 6    6 赵月  女      91      91

# 7    7 朱忻  女      90      88

# 8    8 陈振  男      81      77

# 9    9 武琳  女      80      85

# 10  10 孙晔  女      76      90

#### 4.1 根据某一元素,提取行,然后存为一个新的数据框

#@ 提取数据框df中所有男生的信息

df_new1 <- df[which(df$性别 == "男"),]

df_new1

编号 姓名 性别 数学成绩 语文成绩

1    1 王明  男      90      91

2    2 李磊  男      88      75

3    3 张乐  男      80      83

4    4 刘能  男      70      89

8    8 陈振  男      81      77

#@ 提取数据框df中所有女生的信息

df_new2 <- df[which(df$性别 == "女"),]

df_new2

# 编号 姓名 性别 数学成绩 语文成绩

# 5    5 黄粲  女      95      90

# 6    6 赵月  女      91      91

# 7    7 朱忻  女      90      88

# 9    9 武琳  女      80      85

# 10  10 孙晔  女      76      90

#### 4.2 根据某一个元素,提取列,然后另存为一个新的数据框

df_new3 <- df[,4:5]

df_new3

# 数学成绩 语文成绩

# 1        90      91

# 2        88      75

# 3        80      83

# 4        70      89

# 5        95      90

# 6        91      91

# 7        90      88

# 8        81      77

# 9        80      85

# 10      76      90

df_new4 <- df[2:4, 2:4] # 提取数据框的一小部分:子集

df_new4

# 姓名 性别 数学成绩

# 2 李磊  男      88

# 3 张乐  男      80

# 4 刘能  男      70

df[2,2]

# [1] 李磊

# 10 Levels: 陈振 黄粲 李磊 刘能 孙晔 王明 武琳 张乐 ... 朱忻

df[3,3]

# [1] 男

# Levels: 男 女

df[4,4]

# [1] 70

#@ 根据条件筛选数据框

df_new5 <- df[df$数学成绩 > 80,]

df_new5

# 编号 姓名 性别 数学成绩 语文成绩

# 1    1 王明  男      90      91

# 2    2 李磊  男      88      75

# 5    5 黄粲  女      95      90

# 6    6 赵月  女      91      91

# 7    7 朱忻  女      90      88

# 8    8 陈振  男      81      77

df_new6 <- df[df$语文成绩 == 91,]

df_new6

# 编号 姓名 性别 数学成绩 语文成绩

# 1    1 王明  男      90      91

# 6    6 赵月  女      91      91

#@ 多条件判断进行数据框的筛选

df_new7 <- df[c(df$性别 == "男" & df$数学成绩 == 90),]

df_new7

# 编号 姓名 性别 数学成绩 语文成绩

# 1    1 王明  男      90      91

df_new8 <- df[df$性别 == "女" & df$数学成绩 > 90 & df$语文成绩 >90,]

df_new8

# 编号 姓名 性别 数学成绩 语文成绩

# 6    6 赵月  女      91      91

### 5.数据框的排序问题

#### 5.1 按照某一列进行排序

#@ 默认是升序排序,由低到高排序

df_new9 <- df[order(df$数学成绩),]

df_new9

# 编号 姓名 性别 数学成绩 语文成绩

# 4    4 刘能  男      70      89

# 10  10 孙晔  女      76      90

# 3    3 张乐  男      80      83

# 9    9 武琳  女      80      85

# 8    8 陈振  男      81      77

# 2    2 李磊  男      88      75

# 1    1 王明  男      90      91

# 7    7 朱忻  女      90      88

# 6    6 赵月  女      91      91

# 5    5 黄粲  女      95      90

#@ 也可以降序排序:由高到低进行

df_new10 <- df[order(-df$数学成绩),]

df_new10

# 编号 姓名 性别 数学成绩 语文成绩

# 5    5 黄粲  女      95      90

# 6    6 赵月  女      91      91

# 1    1 王明  男      90      91

# 7    7 朱忻  女      90      88

# 2    2 李磊  男      88      75

# 8    8 陈振  男      81      77

# 3    3 张乐  男      80      83

# 9    9 武琳  女      80      85

# 10  10 孙晔  女      76      90

# 4    4 刘能  男      70      89

#### 5.2 按照多个列进行排序

#@ 多列同为升序排序,有主次之分,第一个是主要的,先排第一个OK了之后,再排第二个,考虑到一列有相同的排序,第二列、第三列大小不一……,才可以区分开

df_new11 <- df[order(df$数学成绩, df$语文成绩),]

df_new11

# 编号 姓名 性别 数学成绩 语文成绩

# 4    4 刘能  男      70      89

# 10  10 孙晔  女      76      90

# 3    3 张乐  男      80      83

# 9    9 武琳  女      80      85

# 8    8 陈振  男      81      77

# 2    2 李磊  男      88      75

# 7    7 朱忻  女      90      88

# 1    1 王明  男      90      91

# 6    6 赵月  女      91      91

# 5    5 黄粲  女      95      90

#@ 多列排序,一个为升序,一个为降序

df_new12 <- df[order(-df$数学成绩, df$语文成绩),]

df_new12

# 编号 姓名 性别 数学成绩 语文成绩

# 5    5 黄粲  女      95      90

# 6    6 赵月  女      91      91

# 7    7 朱忻  女      90      88

# 1    1 王明  男      90      91

# 2    2 李磊  男      88      75

# 8    8 陈振  男      81      77

# 3    3 张乐  男      80      83

# 9    9 武琳  女      80      85

# 10  10 孙晔  女      76      90

# 4    4 刘能  男      70      89

#@ 多列都为降序排序

df_new13 <- df[order(-df$数学成绩, -df$语文成绩),]

df_new13

# 编号 姓名 性别 数学成绩 语文成绩

# 5    5 黄粲  女      95      90

# 6    6 赵月  女      91      91

# 1    1 王明  男      90      91

# 7    7 朱忻  女      90      88

# 2    2 李磊  男      88      75

# 8    8 陈振  男      81      77

# 9    9 武琳  女      80      85

# 3    3 张乐  男      80      83

# 10  10 孙晔  女      76      90

# 4    4 刘能  男      70      89

 

### 6.数据框的分离与合并问题

#### 6.1 数据框分离,其实就是获取数据框的子集问题,方法有很多

#@ 利用数据框行列位置索引获取新的数据集

df

# 编号 姓名 性别 数学成绩 语文成绩

# 1    1 王明  男      90      91

# 2    2 李磊  男      88      75

# 3    3 张乐  男      80      83

# 4    4 刘能  男      70      89

# 5    5 黄粲  女      95      90

# 6    6 赵月  女      91      91

# 7    7 朱忻  女      90      88

# 8    8 陈振  男      81      77

# 9    9 武琳  女      80      85

# 10  10 孙晔  女      76      90

df_new14 <- df[,1:3]

df_new14

# 编号 姓名 性别

# 1    1 王明  男

# 2    2 李磊  男

# 3    3 张乐  男

# 4    4 刘能  男

# 5    5 黄粲  女

# 6    6 赵月  女

# 7    7 朱忻  女

# 8    8 陈振  男

# 9    9 武琳  女

# 10  10 孙晔  女

df_new15 <- df[2:5,]

df_new15

# 编号 姓名 性别 数学成绩 语文成绩

# 2    2 李磊  男      88      75

# 3    3 张乐  男      80      83

# 4    4 刘能  男      70      89

# 5    5 黄粲  女      95      90

#### 6.2 根据数据框的行名和列名进行子集的提取

#@ 根据行名进行提取数据框子集,为了方便识别,我们重新定义一个数据框df的行名

row.names(df) <- df$姓名

df

# 编号 姓名 性别 数学成绩 语文成绩

# 王明    1 王明  男      90      91

# 李磊    2 李磊  男      88      75

# 张乐    3 张乐  男      80      83

# 刘能    4 刘能  男      70      89

# 黄粲    5 黄粲  女      95      90

# 赵月    6 赵月  女      91      91

# 朱忻    7 朱忻  女      90      88

# 陈振    8 陈振  男      81      77

# 武琳    9 武琳  女      80      85

# 孙晔  10 孙晔  女      76      90

df_new16 <- df[c("王明", "赵月", "孙晔"),]

df_new16

# 编号 姓名 性别 数学成绩 语文成绩

# 王明    1 王明  男      90      91

# 赵月    6 赵月  女      91      91

# 孙晔  10 孙晔  女      76      90

#@ 根据列名进行数据框子集的提取

df_new17 <- df[,c("数学成绩", "语文成绩")]

df_new17

# 数学成绩 语文成绩

# 王明      90      91

# 李磊      88      75

# 张乐      80      83

# 刘能      70      89

# 黄粲      95      90

# 赵月      91      91

# 朱忻      90      88

# 陈振      81      77

# 武琳      80      85

# 孙晔      76      90

df_new18 <- df[c("王明", "赵月", "孙晔"), c("数学成绩", "语文成绩")]

df_new18

# 数学成绩 语文成绩

# 王明      90      91

# 赵月      91      91

# 孙晔      76      90

#### 6.3 subset函数提取数据框子集

df_new19 <- subset(df, select = 数学成绩)

df_new19

# 数学成绩

# 王明      90

# 李磊      88

# 张乐      80

# 刘能      70

# 黄粲      95

# 赵月      91

# 朱忻      90

# 陈振      81

# 武琳      80

# 孙晔      76

#@ 根据列名范围进行筛选

df_new20 <- subset(df, select = 数学成绩:语文成绩)

df_new20

# 数学成绩 语文成绩

# 王明      90      91

# 李磊      88      75

# 张乐      80      83

# 刘能      70      89

# 黄粲      95      90

# 赵月      91      91

# 朱忻      90      88

# 陈振      81      77

# 武琳      80      85

# 孙晔      76      90

#@ 有条件的筛选某一列数据

df_new21 <- subset(df, 数学成绩> 80, select = 语文成绩)

df_new21

# 语文成绩

# 王明      91

# 李磊      75

# 黄粲      90

# 赵月      91

# 朱忻      88

# 陈振      77

#### 6.4 dplyr包中的%in%和select()函数

df_new22 <- dplyr::select(df,数学成绩)

df_new22

# 数学成绩

# 王明      90

# 李磊      88

# 张乐      80

# 刘能      70

# 黄粲      95

# 赵月      91

# 朱忻      90

# 陈振      81

# 武琳      80

# 孙晔      76

df_new23 <- dplyr::select(df, 数学成绩, 语文成绩)

df_new23

# 数学成绩 语文成绩

# 王明      90      91

# 李磊      88      75

# 张乐      80      83

# 刘能      70      89

# 黄粲      95      90

# 赵月      91      91

# 朱忻      90      88

# 陈振      81      77

# 武琳      80      85

# 孙晔      76      90

#### 6.5 数据框的合并方法也有很多

#@ 按列进行合并,行数必须相同

df_new24 <- cbind(df_new13, df_new14)

df_new24

# 编号 姓名 性别 数学成绩 语文成绩 编号 姓名 性别

# 5    5 黄粲  女      95      90    1 王明  男

# 6    6 赵月  女      91      91    2 李磊  男

# 1    1 王明  男      90      91    3 张乐  男

# 7    7 朱忻  女      90      88    4 刘能  男

# 2    2 李磊  男      88      75    5 黄粲  女

# 8    8 陈振  男      81      77    6 赵月  女

# 9    9 武琳  女      80      85    7 朱忻  女

# 3    3 张乐  男      80      83    8 陈振  男

# 10  10 孙晔  女      76      90    9 武琳  女

# 4    4 刘能  男      70      89  10 孙晔  女

#@ 按行进行合并,列数必须相同

df_new25 <- rbind(df_new18, df_new20)

df_new25

# 数学成绩 语文成绩

# 王明        90      91

# 赵月        91      91

# 孙晔        76      90

# 王明1      90      91

# 李磊        88      75

# 张乐        80      83

# 刘能        70      89

# 黄粲        95      90

# 赵月1      91      91

# 朱忻        90      88

# 陈振        81      77

# 武琳        80      85

# 孙晔1      76      90

#@ merge合并,两个数据框根据相同的列进行合并:merge(),merge.data.frame()

#@ 主要参数有by.x,by.y和all.x,all.y和all,设置合理就会得到你想要的结果,不合理的话可能啥也没有

df_new26 <- merge(x = df_new2, y = df_new5, by.x = "姓名", by.y = "姓名", all = T)

df_new26

# 姓名 编号.x 性别.x 数学成绩.x 语文成绩.x 编号.y 性别.y

# 1 陈振    NA                    8    男

# 2 黄粲      5    女        95        90      5    女

# 3 李磊    NA                    2    男

# 4 孙晔    10    女        76        90    NA 

#  5 王明    NA                    1    男

# 6 武琳      9    女        80        85    NA 

#  7 赵月      6    女        91        91      6    女

# 8 朱忻      7    女        90        88      7    女

# 数学成绩.y 语文成绩.y

# 1        81        77

# 2        95        90

# 3        88        75

# 4        NA        NA

# 5        90        91

# 6        NA        NA

# 7        91        91

# 8        90        88

### 7.数据框的转置问题

df_t <- t(df)

df_t

# [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7] 

# 编号    " 1"  " 2"  " 3"  " 4"  " 5"  " 6"  " 7" 

# 姓名    "王明" "李磊" "张乐" "刘能" "黄粲" "赵月" "朱忻"

# 性别    "男"  "男"  "男"  "男"  "女"  "女"  "女" 

# 数学成绩 "90"  "88"  "80"  "70"  "95"  "91"  "90" 

# 语文成绩 "91"  "75"  "83"  "89"  "90"  "91"  "88" 

# [,8]  [,9]  [,10]

# 编号    " 8"  " 9"  "10" 

# 姓名    "陈振" "武琳" "孙晔"

# 性别    "男"  "女"  "女" 

# 数学成绩 "81"  "80"  "76" 

# 语文成绩 "77"  "85"  "90" 

#@ 转置之后的数据结构类型发生了变化

class(df_t)

# [1] "matrix"

#@ 且无法强制转换

df_t_new < -as.data.frame(t(df))

# 错误: 找不到对象'df_t_new'

### 8.数据框的删除、增加和替换问题


#### 8.1 删除数据框某一列或多列

df

# 编号 姓名 性别 数学成绩 语文成绩

# 王明    1 王明  男      90      91

# 李磊    2 李磊  男      88      75

# 张乐    3 张乐  男      80      83

# 刘能    4 刘能  男      70      89

# 黄粲    5 黄粲  女      95      90

# 赵月    6 赵月  女      91      91

# 朱忻    7 朱忻  女      90      88

# 陈振    8 陈振  男      81      77

# 武琳    9 武琳  女      80      85

# 孙晔  10 孙晔  女      76      90

dim(df)

# [1] 10  5

df_new1

# 编号 姓名 性别 数学成绩 语文成绩

# 1    1 王明  男      90      91

# 2    2 李磊  男      88      75

# 3    3 张乐  男      80      83

# 4    4 刘能  男      70      89

# 8    8 陈振  男      81      77

df_new1$编号 <- NULL

df_new1

# 姓名 性别 数学成绩 语文成绩

# 1 王明  男      90      91

# 2 李磊  男      88      75

# 3 张乐  男      80      83

# 4 刘能  男      70      89

# 8 陈振  男      81      77

df_new1[,2:4] <- NULL

df_new1

# 姓名

# 1 王明

# 2 李磊

# 3 张乐

# 4 刘能

# 8 陈振

#### 8.2 删除数据框某一行或多行

df_new2

# 编号 姓名 性别 数学成绩 语文成绩

# 5    5 黄粲  女      95      90

# 6    6 赵月  女      91      91

# 7    7 朱忻  女      90      88

# 9    9 武琳  女      80      85

# 10  10 孙晔  女      76      90

df_new2[1,] <- NULL

# Error in x[[jj]][iseq] <- vjj : 更换参数长度为零

df_new2[1,] <- ""

# Warning messages:

#  1: In `[<-.factor`(`*tmp*`, iseq, value = "") :

#  invalid factor level, NA generated

# 2: In `[<-.factor`(`*tmp*`, iseq, value = "") :

#  invalid factor level, NA generated

# 3: In `[<-.factor`(`*tmp*`, iseq, value = "") :

#  invalid factor level, NA generated

# 4: In `[<-.factor`(`*tmp*`, iseq, value = "") :

#  invalid factor level, NA generated

df_new2

# 编号 姓名 性别 数学成绩 语文成绩

# 5             

# 6    6 赵月  女      91      91

# 7    7 朱忻  女      90      88

# 9    9 武琳  女      80      85

# 10  10 孙晔  女      76      90

df_new27 <- df_new2[-c(1),] # 用c()和-的组合,可以很轻松的删除你不想要的行

df_new27

# 编号 姓名 性别 数学成绩 语文成绩

# 6    6 赵月  女      91      91

# 7    7 朱忻  女      90      88

# 9    9 武琳  女      80      85

# 10  10 孙晔  女      76      90

df_new3

# 数学成绩 语文成绩

# 1        90      91

# 2        88      75

# 3        80      83

# 4        70      89

# 5        95      90

# 6        91      91

# 7        90      88

# 8        81      77

# 9        80      85

# 10      76      90

df_new28 <- df_new3[-c(1,3,5,7), ] #删除掉1/3/5/7行

df_new28

# 数学成绩 语文成绩

# 2        88      75

# 4        70      89

# 6        91      91

# 8        81      77

# 9        80      85

# 10      76      90

df_new29 <- df_new3[-c(1:3),] # 也可以指定行的范围进行删除

df_new29

# 数学成绩 语文成绩

# 4        70      89

# 5        95      90

# 6        91      91

# 7        90      88

# 8        81      77

# 9        80      85

# 10      76      90

#### 8.3 替换数据框中的缺失值为0

#@ 咱们先构建一个含有缺失值的数据框

set.seed(110)

m <- matrix(sample(c(NA, 1:10), 100, replace = TRUE), 10)

mydf <- as.data.frame(m)

mydf

# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10

# 1  3  2  4 10 NA  8 NA  7  6  9

# 2  7  2  8  4  4  8  5  6  9  8

# 3  5  9  9  6  8  6  2  3  6  2

# 4  2  9  5  7  5  4  7  7  9  4

# 5  8 NA  9 10  5  4  5  9  2  9

# 6  6  9  6  9  7  3  7 10  1  10

# 7  2 NA  1  3  1  2  7  4  2  5

# 8  8  4 10 NA  3 10  9  9  5  6

# 9  10  6  2 NA  1  5  2  2  9  9

# 10  3  8  8  7  5  2  5  8  7  7

is.na(mydf) # is.na()函数返回数据类型是否是缺失值的真假值

# V1    V2    V3    V4    V5    V6    V7    V8    V9

# [1,] FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE

# [2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [3,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [4,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [5,] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [6,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [7,] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [8,] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE

# [9,] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE

# [10,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# V10

# [1,] FALSE

# [2,] FALSE

# [3,] FALSE

# [4,] FALSE

# [5,] FALSE

# [6,] FALSE

# [7,] FALSE

# [8,] FALSE

# [9,] FALSE

# [10,] FALSE

mydf[is.na(mydf)] <- 0 # 然后数据框根据真假值进行替换0,为真的替换为0,为真就是NA

mydf

# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10

# 1  3  2  4 10  0  8  0  7  6  9

# 2  7  2  8  4  4  8  5  6  9  8

# 3  5  9  9  6  8  6  2  3  6  2

# 4  2  9  5  7  5  4  7  7  9  4

# 5  8  0  9 10  5  4  5  9  2  9

# 6  6  9  6  9  7  3  7 10  1  10

# 7  2  0  1  3  1  2  7  4  2  5

# 8  8  4 10  0  3 10  9  9  5  6

# 9  10  6  2  0  1  5  2  2  9  9

# 10  3  8  8  7  5  2  5  8  7  7

#### 8.4 根据某个元素进行删除行或列

set.seed(110)

mydf2 <- as.data.frame(matrix(sample(c(NA, 1:20), 100, replace = TRUE), 10))

mydf2

# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10

# 1  19 18 11 10  7 19  5  9  2  1

# 2  5  9 13  9  1  2  7 15 20  NA

# 3  18 NA 17  3  3 18  6  2  5  4

# 4  8 NA 13 16  1 NA  3  1  6  4

# 5  15 20  2 16  5  5  7  2 11  7

# 6  6  6 13 NA 13 18  4  5  7  9

# 7  2 20  8  4  8  7 12 11  7  15

# 8  8  8 11  8  6 14  2 12 18  19

# 9  3 11 20  5 20  9  8  8 17  4

# 10 18  9  6  5  4 18 15 11  9  18

#@ 根据某个元素删除行,例如这个元素是NA

mydf2  <- mydf2[complete.cases(mydf2),]

mydf2

# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10

# 1  19 18 11 10  7 19  5  9  2  1

# 5  15 20  2 16  5  5  7  2 11  7

# 7  2 20  8  4  8  7 12 11  7  15

# 8  8  8 11  8  6 14  2 12 18  19

# 9  3 11 20  5 20  9  8  8 17  4

# 10 18  9  6  5  4 18 15 11  9  18

?complete.cases

# Find Complete Cases

# Return a logical vector indicating which cases are complete, i.e., have no missing values.

set.seed(110)

mydf3 <- as.data.frame(matrix(sample(c(NA, 1:10), 100, replace = TRUE), 10))

mydf3

# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10

# 1  3  2  4 10 NA  8 NA  7  6  9

# 2  7  2  8  4  4  8  5  6  9  8

# 3  5  9  9  6  8  6  2  3  6  2

# 4  2  9  5  7  5  4  7  7  9  4

# 5  8 NA  9 10  5  4  5  9  2  9

# 6  6  9  6  9  7  3  7 10  1  10

# 7  2 NA  1  3  1  2  7  4  2  5

# 8  8  4 10 NA  3 10  9  9  5  6

# 9  10  6  2 NA  1  5  2  2  9  9

# 10  3  8  8  7  5  2  5  8  7  7

mydf3 <- na.omit(mydf3)

mydf3

# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10

# 2  7  2  8  4  4  8  5  6  9  8

# 3  5  9  9  6  8  6  2  3  6  2

# 4  2  9  5  7  5  4  7  7  9  4

# 6  6  9  6  9  7  3  7 10  1  10

# 10  3  8  8  7  5  2  5  8  7  7

?na.omit

# Handle Missing Values in Objects

#@ 根据某个元素删除列,例如这个元素是NA

set.seed(110)

mydf4 <- as.data.frame(matrix(sample(c(NA, 1:30), 100, replace = TRUE), 10))

mydf4

# V1 V2 V3 V4 V5 V6 V7 V8 V9 V10

# 1  19  3 27 11  8 16  3  4 14  7

# 2  23 18 27 30 26 23  1 19 21  25

# 3  5 18  6 22 11 NA  5  2 23  26

# 4  18 30 24 13 20  4 27 26 23  4

# 5  8 25 20 17  6  8 13 21  9  12

# 6  15  9  8 26 23 29 29 18 18  25

# 7  6 NA 11 13 10  5  8 NA  5  2

# 8  2 25 25  2  9  5 24  5  7  8

# 9  8 NA 21 13  3  7  6 18  6  28

# 10 26 20  9 28 16  1 20  7  3  15

is.na(mydf4)

# V1    V2    V3    V4    V5    V6    V7    V8    V9

# [1,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [2,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [3,] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE

# [4,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [5,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [6,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [7,] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE

# [8,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [9,] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# [10,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

# V10

# [1,] FALSE

# [2,] FALSE

# [3,] FALSE

# [4,] FALSE

# [5,] FALSE

# [6,] FALSE

# [7,] FALSE

# [8,] FALSE

# [9,] FALSE

# [10,] FALSE

na_flag <- apply(is.na(mydf4), 2, sum)

mydf4 <- mydf4[,which(na_flag == 0)]

mydf4

# V1 V3 V4 V5 V7 V9 V10

# 1  19 27 11  8  3 14  7

# 2  23 27 30 26  1 21  25

# 3  5  6 22 11  5 23  26

# 4  18 24 13 20 27 23  4

# 5  8 20 17  6 13  9  12

# 6  15  8 26 23 29 18  25

# 7  6 11 13 10  8  5  2

# 8  2 25  2  9 24  7  8

# 9  8 21 13  3  6  6  28

# 10 26  9 28 16 20  3  15

三、收官

sessionInfo()

# R version 3.6.2 (2019-12-12)

# Platform: x86_64-w64-mingw32/x64 (64-bit)

# Running under: Windows 10 x64 (build 18363)

#

# Matrix products: default

#

# locale:

#  [1] LC_COLLATE=Chinese (Simplified)_China.936

# [2] LC_CTYPE=Chinese (Simplified)_China.936 

# [3] LC_MONETARY=Chinese (Simplified)_China.936

# [4] LC_NUMERIC=C                             

# [5] LC_TIME=Chinese (Simplified)_China.936   

#

# attached base packages:

#  [1] stats    graphics  grDevices utils    datasets

# [6] methods  base   

#

# other attached packages:

#  [1] chron_2.3-54  sqldf_0.4-11  RSQLite_2.1.5 gsubfn_0.7 

# [5] proto_1.0.0 

#

# loaded via a namespace (and not attached):

#  [1] zip_2.0.4        Rcpp_1.0.3        cellranger_1.1.0

# [4] pillar_1.4.3      compiler_3.6.2    forcats_0.4.0   

# [7] tools_3.6.2      zeallot_0.1.0    digest_0.6.23   

# [10] packrat_0.5.0    bit_1.1-14        memoise_1.1.0   

# [13] tibble_2.1.3      pkgconfig_2.0.3  rlang_0.4.2     

# [16] openxlsx_4.1.4    DBI_1.1.0        rstudioapi_0.10 

# [19] curl_4.3          haven_2.2.0      rio_0.5.16     

# [22] dplyr_0.8.3      vctrs_0.2.1      hms_0.5.2       

# [25] tidyselect_0.2.5  bit64_0.9-7      glue_1.3.1     

# [28] data.table_1.12.8 R6_2.4.1          tcltk_3.6.2     

# [31] readxl_1.3.1      foreign_0.8-72    purrr_0.3.3     

# [34] blob_1.2.0        magrittr_1.5      backports_1.1.5 

# [37] assertthat_0.2.1  stringi_1.4.3    crayon_1.3.4   

你可能感兴趣的:(R)