数据框(data.frame)是最常用的数据结构,用于存储二维表(即关系表)的数据,每一列存储的数据类型必须相同,不同数据列的数据类型可以相同,也可以不同,但是每列的行数(长度)必须相同。数据框的每列都有唯一的名字,在已创建的数据框上,用户可以添加计算列,这样,R引擎根据同一行的数据列,计算出表达式的值,并把该值作为计算列的值。数据框是数据分析中最重要的数据对象,必须熟练掌握数据框的操作。

一,创建数据框

创建数据框,常用的方式是:读取文件、读取关系表和使用函数创建,用户应根据实际的需要,选择合适的方式创建数据框。

1,读取文件

第一种方法是通过读取文件创建,常用的是用于读取文件的函数是read.table(),语法是如下所示:

read.table(file, header = FALSE, sep = "", quote = "\"'",
dec = ".", numerals = c("allow.loss", "warn.loss", "no.loss"),
row.names, col.names, as.is = !stringsAsFactors,
na.strings = "NA", colClasses = NA, nrows = -1,
skip = 0, check.names = TRUE, fill = !blank.lines.skip,
strip.white = FALSE, blank.lines.skip = TRUE,
comment.char = "#",
allowEscapes = FALSE, flush = FALSE,
stringsAsFactors = default.stringsAsFactors(),
fileEncoding = "", encoding = "unknown", text, skipNul = FALSE)

参数释义:

  • file:读取数据的文件名和路径,文件名可以是文件的绝对路径名,或是相对路径名,如果文件名是相对路径名,那么文件名是基于当前的工作目录,当前的工作目录可以通过函数 getwd() 获取;
  • header:逻辑值,文件的第一行是否包含列名;
  • sep:用于指定字段(列)的分隔符,默认值是空字符,行的分隔符是回车和换行;
  • quote:字符的引用符,只有当文本使用引用符,才被视为字符,设置为空字符,禁用引用符;
  • dec:小数点符号;
  • check.names:逻辑值,是否检查列名是否符合变量的命名规范;
  • colClasses:用于指定列的数据类型;
  • fill:逻辑值,当设置为TRUE时,如果行的列数不够,那么填充空白的字段;
  • strip.white:逻辑值,只有当sep参数指定时,用于移除字符字段两端的空格;
  • blank.lines.skip :逻辑值,当为TRUE时,跳过空白的数据行;
  • encoding :字符串,用于指定字符的编码规则,常用的编码规则是UTF-8;
  • nrows :整数值,能够读取的最大数据行数量;
  • skip:整数值,从文件的开头,跳过一定数量的数据行,从下一行开始读取数据;

函数read.csv()是read.table()的包装函数,专门用于读取csv文件,例如:

df <- read.csv('D:/data.csv', check.names = FALSE, encoding = "UTF-8", blank.lines.skip = FALSE);

2,读取关系表数据

第二种方法是从关系型数据库执行SQL查询,根据查询结果创建数据框;当连接SQL Server数据库时,使用ODBC驱动程序连接数据库,R脚本引用RODBC包,调用odbcConnect连接,使用sqlQuery执行查询,获取查询结果填充数据框:

library(RODBC)
cn <- odbcConnect("data source")
df <- sqlQuery(cn,"TSQL Query")
odbcClose(cn)

3,使用函数创建

第三种方法是通过函数 data.frame()创建数据框,用户需要输入指定的数据填充数据框变量,函数data.frame()的参数row.names用于指定行的标识符,有三种指定行标识符的方式:

  • 设置行的名称,为每一行命名,这样,可以通过行名称来索引观测;
  • 把该参数设置为NULL,取消行的命名,R引擎会自动生成递增的整数序列作为行标识符,也就是所谓的行号;
  • 也可以把行标识符设置为数据框的列名,这样,R引擎把该列的值作为行标识符,这相当于关系表的主键列。

例如,以下脚本通过指定行名称的方式来指定行标识符:

df <- data.frame(
c1=letters[:],
c2=c(:),
c3=runif()>0.5,
c4=c('r','g','b'),
row.names=c('r1','r2','r3')
)

打印数据框,数据框有两个维度,行和列:

> df
c1 c2 c3 c4
r1 a TRUE r
r2 b FALSE g
r3 c FALSE b

二,查看数据框的元数据

数据框本身存储列的名称、行名称、列数量、和行的数量等元数据。

1,查看列和行的名称

通过函数colnames()或names()返回数据框的列名称,通过函数rownames()返回数据框的行名称,

> colnames(df)
> names(df)
[] "c1" "c2" "c3" "c4"
> rownames(df)
[] "r1" "r2" "r3"

2,查看行和列的数量

通过函数nrow()或函数ncol(),返回数据框的行数或列),函数length()返回的结果和ncol()函数返回的结果相同。

> nrow(df)
[]
> ncol(df)
[]

三,索引数据框

索引数据框,使用中括号[]和下标来访问数据框,和索引向量一项,索引数据框的下标也有四种表示方式:正整数、负整数、逻辑值和名称(行或列的名称)。由于数据框是二维数据结构,有行和列,因此,下标的格式是[row,col], row是行下标,用于选择行;col是列下标,用于选择列。对于row和col,在索引数据框时,必须同时指定这两个下标:

  • 第一个下标用于选择行,如果row是空白的,[ ,col]  表示选择所有的行;
  • 第二个下标用于选择列,[row, ] 表示选择所有列。

索引数据框,也可以设置逻辑向量为下标,而逻辑向量可以由向量的表达式来获得,这使得数据框的索引较为复杂。不过,只要理解下标的四种表示方式,不过怎么组合,都不难掌握。

1,选择多列

例如,获得数据框的一个子集,索引数据框中的第一行和第二行,第二列和第三列的数据子集:

> df[:,:]
c2 c3
r1 TRUE
r2 FALSE

2,使用名称来索引数据框

如果只选择数据框的一列,可以使用:美元符号(&) + 列名称 来选择单列,在使用 下标和 [ ] 来选择行。

例如,通过美元符号$和列名来索引数据框的列c1,通过下标和[]来选取第二行和第三行:

> df$c1[:]
[] b c
Levels: a b c

从返回的结果中可以看到,R引擎把字符类型的列自动转换为因子类型来存储,可以使用as.character()函数把因子类型转换为字符类型的向量:

> as.character(df$c1[:])
[] "b" "c"

如果要引用单列的所有行,可以不对行进行过滤,使用 "&+ 列名", 返回该列的所有数据行,例如:

df$c1

使用这种方式索引数据框,得到的是向量,其行为和普通的向量相同,支持向量运算。

3,下标为逻辑向量

逻辑向量,通常是由向量的条件表达式计算得到的,例如:

> df$c2>
[] FALSE TRUE TRUE

查看逻辑向量的元素值,为TRUE的位置刚好是数据框c2列中大于1的行,因此,可以通过这种方式,按照特定的条件获取数据框的子集,例如,获取数据框中c2列大于1的数据行:

> df[df$c2>, ]
c1 c2 c3 c4
r2 b FALSE g
r3 c TRUE b

当然,也可以使用逻辑运算符,组合多个条件,获得满足条件的所有数据行,例如:

df[df$c2> & df$c, ]

4,小标为列名

当使用两个中括号时,第一个中括号内指的是列名,包括所有数据行:

df['c1']

第二个中括号是行选择器:

> df['c1'][df['c2']>1]
[] "b" "c"

举个例子,第一个中括号索引c2列的所有的行,第二个中括号对行进行筛选,只选择c2的值<=2的行:

df[,'c2'][df[,'c2']<=2]

四,获取数据框的子集

从数据框中按照特定的条件获取子集,这实际上是根据特定列的值,来限制返回的观测的数量。

1,通过设置行索引获取子集

这是利用数据框的下标为逻辑向量来过滤数据行,由于索引数据框,需要多次书写数据框的名称,df[df$c2<= df | c3, ] ,十分麻烦,为了简化流程,可以使用函数with()或within(),这样,可以省略数据框名称和$符号,例如:

> with(df,df[c2<=|c3,])
c1 c2 c3 c4
r1 a FALSE r
r2 b TRUE g

2,通过subset()函数获取子集

函数subset()用于获取数据框的子集,第一个参数(x)是数据框;第二个参数(subset)是逻辑表达式,用于过滤数据行;第三个参数(select)是投影的数据列,用于选择的特定的列。

subset(x, subset, select, drop = FALSE)

例如,从df中获取c2不大于2,返回第二列和第三列的结果:

> subset(df,c2<=,c(:))
c2 c3
r1 TRUE
r2 FALSE

五,数据框的基本操作

操纵数据框,例如,选择子集(subset),合并数据框,排序数据框,添加或修改数据列,把数据值排名等,最终把数据转换成相应的形式,用于数据分析,本节只简单分享操纵数据框的方法。

1,添加列和行

使用rbind()函数向数据框中添加一行或多行数据,也就是说,按行纵向扩展;使用cbind()函数向数据框中添加一列或多列数据,也就是说,按列横向扩展。

2,合并数据框

使用merge9)函数合并数据框,merge()函数的作用类似于SQL语言中的连接(Join)操作,用于把两个数据框,按照特定的数据列做连接操作,函数的定义如下:

merge(x, y,
by = intersect(names(x), names(y)), by.x = by, by.y = by,
all = FALSE, all.x = all, all.y = all,
sort = TRUE,
suffixes = c(".x",".y"),...)

参数注释:

  • x,y 参数:指定合并的两个数据框;
  • by参数:字符串,指定合并列,当两个数据框有相同的数据列名字时,merge函数将按照同名的数据列名称合并;
  • by.x,by.y 参数:字符串,分别指定数据框的合并列,用于指定merge函数将按照数据框x和y的哪些数据列进行合并;
  • all:逻辑值,完全显示两个数据框的所有数据行,当合并列的值不存在于数据框x或y中,该数据框的列值显示为NA;
  • all.x,all.y:逻辑值,指定完全显示的数据框,例如,当折merge函数的all.x=TRUE,all.y=FALSE是,合并的结果把数据框x的数据列全部显示,如果合并列的值不存在于数据框y,那么y的其他数据列显示为NA。
  • sort:逻辑值,指定是否对结果排序;
  • suffixes:为非合并列添加后缀;

例如,创建两个数据框,按照df1的数据列x,和数据框df2的数据列m,对这两个数据框执行合并操作:

> df1=data.frame(x=c('a','c','e'),y=:)
> df2=data.frame(m=c('a','c','f'),n=:)
> merge(df1,df2,by.x='x',by.y='m')
x y n
a
c
>
> merge(df1,df2,by.x='x',by.y='m',all=TRUE)
x y n
a
c
e NA
f NA

2,添加和替换列

方法1:直接对数据框的数据列进行赋值,来实现对数据框的数据列的添加或替换:

df1[,'z'] <- c('z1','z2','z3')
df1$z <- c('z1','z2','z3')

方法2:使用with参数,with函数(with(data, expr))接受一个数据框对象和要计算的表达式作为输入参数,with函数返回值是表达式的值,with函数只能添加或修改一个数据列:

df1 <- with(df1,{z=c('z1','z2','z3')})

方法3:使用within函数,within函数(within(data, expr))接受一个数据框对象和要计算的表达式作为输入参数,within函数返回的是更新后的数据框对象,within函数可以在大括号中添加多个表达式,能够一次操作多个数据列:

df1 <- within(df1,{z=c('z1','z2','z3')} )

方法4:使用plyr包中的mutate函数,该函数用于向数据框中添加数据列或转换已经存在的数据列,接受一个数据框对象,和多个”name=value“对,返回修改后的数据框对象:

df1 <- df1 %>% mutate(z=c('z1','z2','z3'))

3,排序

order()函数能够对数据框进行排序,order(x)函数:返回第i个元素是x中元素在排序之后的序号,对数据框进行排序时,可以分两步进行下去,第一步获取行的序号,第二部按照行号查询数据框:

> y_order <- order(df1[,'y'])
> df1[y_order,]

还有一个方法,使用dplyr包中的arrange函数,只用一行就能实现对数据框的排序:

arrange(df1,y)

4,排名

rank()函数可以为数据框中的列进行排名,不过rank()函数只能作用于向量,只能返回向量元素的排名:

rank(x, na.last = TRUE, ties.method = c("average", "first", "last", "random", "max", "min"))

操作数据框,在数据分析中占用很大的比重,后续,我们再深入探讨。

R语言学习 第三篇:数据框的更多相关文章

  1. R语言学习 第四篇:函数和流程控制

    变量用于临时存储数据,而函数用于操作数据,实现代码的重复使用.在R中,函数只是另一种数据类型的变量,可以被分配,操作,甚至把函数作为参数传递给其他函数.分支控制和循环控制,和通用编程语言的风格很相似, ...

  2. R语言学习 第十一篇:日期和时间

    R语言的基础包中提供了三种基本类型用于处理日期和时间,Date用于处理日期,它不包括时间和时区信息:POSIXct/POSIXlt用于处理日期和时间,其中包括了日期.时间和时区信息.R内部在存储日期和 ...

  3. R语言学习 第八篇:常用的数据处理函数

    Basic包是R语言预装的开发包,包含了常用的数据处理函数,可以对数据进行简单地清理和转换,也可以在使用其他转换函数之前,对数据进行预处理,必须熟练掌握常用的数据处理函数,本文分享在数据处理时,经常使 ...

  4. R语言学习 第七篇:列表

    列表(List)是R中最复杂的数据类型,一般来说,列表是数据对象的有序集合,但是,列表的各个元素(item)的数据类型可以不同,每个元素的长度可以不同,是R中最灵活的数据类型.列表项可以是列表类型,因 ...

  5. R语言学习 第十篇:操作符

    运算符是R语言中最基础的存在,熟悉运算符的使用,是熟练使用R处理数据的基础,操作符,顾名思义,是对数据进行运算的符号,R有自己的一套操作符,实现变量的赋值,引用,运算等功能. 一,赋值符号 为变量赋值 ...

  6. R语言学习 第五篇:字符串操作

    文本数据存储在字符向量中,字符向量的每个元素都是字符串,而非单独的字符.在R中,可以使用双引号,或单引号表示字符. 一,字符串中的字符数量 函数nchar()用于获得字符串中的字符数量: > s ...

  7. R语言学习 第十篇:包

    包(Package)是实现特定功能的.预先写好的代码库(library),通俗地说,包是含有函数.数据等的功能模块.R拥有大量的软件包,许多包都是由某一领域的专家编写的,但并不是所有的包都有很高的质量 ...

  8. R语言学习笔记:取数据子集

    上文介绍了,如何生成序列,本文介绍一下如何取出其数据子集 取出元素的逻辑值 > x<-c(0,-3,4,-1,45,90,5) > x>0 [1] FALSE FALSE  T ...

  9. R语言学习笔记:读取前n行数据

    常规读取 一般我们读取文件时都会读取全部的文件然后再进行操作,因为R是基于内存进行计算的. data <- read.table("C:\\Users\\Hider\\Desktop\ ...

随机推荐

  1. JavaScript动画:offset和匀速动画详解(含轮播图的实现)

    本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. offset简介 我们知道,三大家族包括:offset/scroll/c ...

  2. 什么是 Azure 中的虚拟机规模集?

    虚拟机规模集是一种 Azure 计算资源,可用于部署和管理一组相同的 VM. 由于所有 VM 的配置都相同,因此无需对 VM 进行任何预先配置. 这样就可以更方便地构建面向大型计算.大数据.容器化工作 ...

  3. 使用 PowerShell 管理 Azure 磁盘

    Azure 虚拟机使用磁盘来存储 VM 操作系统.应用程序和数据. 创建 VM 时,请务必选择适用于所需工作负荷的磁盘大小和配置. 本教程介绍如何部署和管理 VM 磁盘. 学习内容: OS 磁盘和临时 ...

  4. 【gp数据库】你一定会用到的运维语句宝典

    -- 查询未空闲的进程信息 select * from pg_stat_activity where current_query<>'<IDLE>'; 结果可查看数据库名,进程 ...

  5. 接口调用,输出结果为Json格式(ConvertTo-Json),提交参数给URL(WebRequest)

    1.直接输出为json格式: Get-Process -Id $pid | ConvertTo-Json | clip.exe 2.自定义结果为json格式: $serverinfoj = @&quo ...

  6. Java 设计模式笔记

    0. 说明 转载 & 参考大部分内容 JAVA设计模式总结之23种设计模式 1. 什么是设计模式 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设 ...

  7. 【转】Java学习---解析Java Servlet工作过程

    [原文]https://www.toutiao.com/i6594316694657696264/ 解析Java Servlet工作过程 Servlet简介 Servlet是sun公司提供的一门用于开 ...

  8. MySQL案列之主从复制出错问题以及pt-slave-restart工具的使用

    今天主从复制遇到一个问题,主库上插入了几百行万数据,后来又删除了这些数据,原因就是主库删除的表从库中不存在,导致从库在遇到删除不存在表的错误无法继续同步. MySQL [(none)]> sho ...

  9. 3.5星|《订阅》:Youtube对用户喜好的发现与应对

    订阅:数字时代的商业变现路径 主要内容我总结是Youtube对用户喜好的发现与应对.可以认为很多时候作者说的是Youtubu官方的态度与想法.穿插了许多Youtube上的成功创作者的故事. Youtu ...

  10. 探索C#字符串

    一.前言 刚接触C#时,书上说string是一种特殊的引用类型,因此string类型变量在作为参数传递到另一个方法,被修改后原变量的值不会发生变化,当时看得我一脸懵逼,什么叫特殊....后来又听说字符 ...