iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >R语言之xlsx包读写Excel数据的操作
  • 631
分享到

R语言之xlsx包读写Excel数据的操作

2024-04-02 19:04:59 631人浏览 独家记忆
摘要

感谢Adrian A. Drǎgulescu发布的xlsx包 xlsx包提供了必要的工具来与excel 2007进行交互。用户可以阅读和编写xlsx,并可以通过设置数据格式、字体、颜

感谢Adrian A. Drǎgulescu发布的xlsx包

xlsx包提供了必要的工具来与excel 2007进行交互。用户可以阅读和编写xlsx,并可以通过设置数据格式、字体、颜色和边框来控制电子表格的外观。设置打印区域,缩放控制,创建分割和冻结面板,添加页眉和页脚。包使用Apache POI项目中的java库。本篇主要分享利用xlsx工具包在读写xlsx过程中所碰到的问题及解决办法。

工具准备

强烈建议大家使用RStudio这个IDE,它是以今为止对R语言最友好的一个IDE之一,而且使用很方便。特别是在新包下载安装的时候,只需请求要安装的包名,RStudio会自动将关联的其他包也一并下载并安装。

安装R、安装RStudio;

一个简单的示例数据(本次以iris鸢尾花数据为例);

下载安装xlsx(Rstudio会同步下载并安装rJava, xlsxjars两个包);


> # 下载并安装xlsx包
> install.packages("xlsx")
> library(xlsx)

【基础】简单读取excel文件数据

假如是csv或txt等文本类的数据文件,利用R内置函数read.csv()与read.table()就可读取(注意编码格式的参数设置)。Excel由于使用范围最广,很多问题不可避免,因此,xlsx包提供了专门读取xlsx的函数read.xlsx和read.xlsx2,为什么有两个呢?请看以下区别:

函数 参数
xlsx::read.xlsx() file, sheetIndex, sheetName=NULL, rowIndex=NULL,startRow=NULL,endRow=NULL, colIndex=NULL,as.data.frame=TRUE, header=TRUE, colClasses=NA,keepFORMulas=FALSE, encoding=“unknown”, passWord=NULL, …
xlsx::read.xlsx2() file, sheetIndex, sheetName=NULL, startRow=1,colIndex=NULL, endRow=NULL, as.data.frame=TRUE, header=TRUE,colClasses=“character”, password=NULL, …

其实只是细微的差别,大家自己体会即可。下面给个参考案例:


> # 指定file和sheetIndex(或sheetName),即可定位到相应的工作表
> data1 <- read.xlsx("iris.xlsx",sheetIndex = 1)
> head(data1)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
5.1 3.5 1.4 0.2 setosa
4.9 3.0 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5.0 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa

【基础】简单写入数据到excel文件

切莫用R内置函数read.csv()与read.table()去生成xlsx文件,会有你意想不到的麻烦,还是采用专业的包来解决问题吧。 xlsx包同样提供了两个写入数据的函数write.xlsx()和write.xlsx2(),其中细微区别自行参透(注意参数 ...)。

函数 参数
xlsx::write.xlsx() x, file, sheetName=“Sheet1”, col.names=TRUE, row.names=TRUE, append=FALSE, showNA=TRUE, password=NULL
xlsx::write.xlsx2() x, file, sheetName=“Sheet1”,col.names=TRUE, row.names=TRUE, append=FALSE, password=NULL, ...

下面是参考案例:


># 指定x待写入数据,file生成的文件名,row.names为false则不生成行名,指定sheet工作表名为Sheet1
>write.xlsx(iris, file = "iris.xlsx", row.names = FALSE, sheetName = "Sheet1")

想必会有人在这里踩坑,大家应该注意到有一个append的参数,是否认为将其值设置为TRUE的话,就可以多次向表中写入数据?那就真踩坑了。查看xlsx包中的注释也很模糊:


> # a logical value indicating if x should be appended to an existing file. 
> # 翻译:一个逻辑值,指示是否应该将x附加到现有文件中

附加到现有文件中,实际上是增加新的sheet,而非在原有sheet工作表中继续增加数据。如需在同一个sheet工作表中多次增加数据,请继续往下看。

【进阶】随心所欲读取excel中的各种信息

说随心所欲 一点不夸张,不仅可以取出excel中的数据,还能识别excel单元格的样式(包括颜色、字体、大小、标注、数据类型等等)。其原理与数据库有点相似,先是定义一个工作簿的对象,再基于工作簿定义里面的工作表,进而逐级查询。下面进行详细介绍:

【样例数据】文件名:iris10.xlsx。

声明一个工作簿对象


> # loadWorkbook(file, password=NULL)  #用于声明一个工作簿对象
> # 提醒:如果excel文件不在工作空间内,file最好指定为绝对路径
> wb <- createWorkbook("iris10.xlsx")

检索工作簿中的sheet


> # sheets <- getSheets(wb)  #用于生成一个list对象,其中包含所有工作表的信息,数据类型为rJava::jobjRef,在此不深入讲解
> sheets <- getSheets(wb)

定位目标sheet


> # 本例只有一个sheet,名称为“Sheet1”
> sheet <- sheets[["Sheet1"]]  # sheet的数据类型为rJava::jobjRef

读取数据【方法一】

上面read.xlsx()方法能够将整个sheet工作表的数据读取出来,在这里提供另一种方法,不过相对麻烦一点,使用的是xlsx::readColumns()函数

函数 参数
xlsx::readColumns() sheet,startColumn,endColumn,startRow,endRow=NULL,as.data.frame=TRUE,header=TRUE, colClasses=NA, …
xlsx::readRows() sheet, startRow, endRow, startColumn, endColumn=NULL

xlsx::readRows()使用起来比较麻烦,不如xlsx::readColumns()好用,有兴趣的可自行研究一下。另外还有两个函数,用于定位表内数据第一行和最后一行的索引(这里与Java的性质一致,从0开始算起)

函数 参数
getFirstRowNum() 无参。该函数必须基于sheet对象
getLastRowNum() 无参。该函数必须基于sheet对象

xlsx::readRows()使用起来比较麻烦,不如xlsx::readColumns()好用,有兴趣的可自行研究一下。另外还有两个函数,用于定位表内数据第一行和最后一行的索引(这里与Java的性质一致,从0开始算起)

函数 参数
getFirstRowNum() 无参。该函数必须基于sheet对象
getLastRowNum() 无参。该函数必须基于sheet对象

下面以xlsx::readColumns()为例获取数据:


> # 该函数必须提供数据的起始列索引值、终止列索引值、起始行索引值、终止行索引值;
> dataTmp <- readColumns(sheet, startColumn = 1, endColumn = 10,
            startRow = sheet$getFirstRowNum()+1, endRow = sheet$getLastRowNum()+1,
            header = T, as.data.frame=TRUE)

as.data.frame=TRUE决定了输出结果为一个数据框。

缺点:在不清楚数据结构的情况下,首行和末行索引值可以求得,但列数一般难以确定,可能导致列缺失或生成多余的列

读取数据【方法二】

另一种方法相对【方法一】要好一点,先是将所有单元格的值获取出来,再生成数据框。(稍微复杂一点)

函数 参数 注释
xlsx::getRows() sheet, rowIndex=NULL 用于获取sheet的每一行数据,返回值list,数据类型为rJava::jobjRef
xlsx::getCells() row, colIndex=NULL, simplify=TRUE 用于获取行内每个单元格的数据,返回值list,数据类型为rJava::jobjRef
xlsx::getCellValue() cell, keepFormulas=FALSE, encoding=“unknown” 用于获取所有单元格的值,返回值list,数据类型为character,长度为数据表m*n

注意:这里连同标题行也作为单元格数据一并获取,并且如果有null值的单元格,会跳过该单元格


> # 获取cells进而获取values
> cells <- sheet %>% getRows() %>% getCells()
> values <- lapply(cells,getCellValue)

values获取出来就如下面这个样子,你会发现value的名称向量,每个值都包含了所在单元格的x、y坐标值。


> names(values)  #查看values的名称向量
 [1] "1.1" "1.2" "1.3" "1.4" "1.5" "2.1" "2.2" "2.3" "2.4" "2.5" "3.1" "3.2" "3.3" "3.4" "3.5" "4.1" 
[17] "4.2" "4.3" "4.4" "4.5" "5.1" "5.2" "5.3" "5.4" "5.5" "6.1" "6.2" "6.3" "6.4" "6.5" "7.1" "7.2" 
[33] "7.3" "7.4" "7.5" "8.1" "8.2" "8.3" "8.4" "8.5" "9.1" "9.2" "9.3" "9.4" "9.5" "10.1" "10.2" "10.3"
[49] "10.4" "10.5" "11.1" "11.2" "11.3" "11.4" "11.5"

将这些坐标值拆分出来,作为等会重排数据的索引


> addresses <- sapply(names(values),FUN = function(x) str_split(string = x,pattern = "[.]"))

接下来就只需要将其进行重排,形成数据框即可。


> datas.name <- vector(mode = "character")  #声明一个空的向量,用来存放标题
> datas <- data.frame()  # 声明一个空的数据框,用来存放目标数据
> # 用sapply代替for做循环,避免占用大量内存。同时注意sapply使用时的环境问题,用.GlobalEnv指向最外层环境的变量。
> # 这里只对数据进行重排,无需进行计算,所以invisible不显示计算结果
> invisible(sapply(addresses,FUN = function(x) {
+  if (x[1] == "1") {
+   .GlobalEnv$datas.name = c(.GlobalEnv$datas.name,.GlobalEnv$values[[1]])
+   .GlobalEnv$values[[1]] <- NULL
+  } else {
+   .GlobalEnv$datas[x[1],x[2]] <- .GlobalEnv$values[[1]]
+   .GlobalEnv$values[[1]] <- NULL
+  }
+ }))
> names(datas) <- datas.name  #最后在添加标题
> View(datas)

得到结果与原excel数据一致

获取单元格样式与获取数据的方式一致,这里不再增加过多篇幅讲解,只做简单介绍。以下函数按函数名字面理解。

函数 参数
xlsx::CellStyle() wb, dataFormat=NULL, alignment=NULL,border=NULL, fill=NULL, font=NULL, cellProtection=NULL
xlsx::setCellStyle() cell, cellStyle
xlsx::getCellStyle() cell
xlsx::createCellComment() cell, string="", author=NULL, visible=TRUE
getCellComment() cell
removeCellComment() cell

其他函数后续如有机会,再做详细介绍吧。

【进阶】随心所欲将数据写入excel文件

我想大家更想看到的就是这部分内容了。确实在日常处理数据时,将数据存储到excel中进行传递是常有的事,谁叫excel是微软亲生的呢。闲话少说,直入正题。

前面基础篇通过write.xlsx()函数将数据写入excel文件中,同时指定sheet名称。但这种写入是一次性的,即一次写入多少就多少。在工作簿里面新增sheet工作表用append控制,但在同个sheet上继续写入数据,会报错:


> write.xlsx(datas,file = "iris10.xlsx",sheetName = "Sheet1",row.names = F,append = T)
Error in .jcall(wb, "Lorg/apache/poi/ss/usermodel/Sheet;", "createSheet", : 
 java.lang.IllegalArgumentException: The workbook already contains a sheet of this name

说是这个名称的sheet已经存在同名的了!

这次我们采用高级一点的方法,跟前面进阶读取数据一样,先是定义一个工作簿的对象,再创建或加载sheet工作表。

函数 参数 注释
xlsx::createWorkbook() type=“xlsx” 用于生成一个新的excel工作簿
xlsx::loadWorkbook() file, password=NULL 用于加载当前已存在的excel工作簿
xlsx::saveWorkbook() wb, file, password=NULL 使用完必须保存工作簿
xlsx::createSheet() wb, sheetName=“Sheet1” 用于生成一个新的sheet工作表
xlsx::removeSheet() wb, sheetName=“Sheet1” 用于删除工作表
xlsx::getSheets() wb 用于获取当前工作簿里的工作表清单,返回值是list
xlsx::aDDDataFrame() x, sheet, col.names=TRUE, row.names=TRUE,startRow=1, 用于获取当前工作簿里的工作表清单,返回值是list
(续上) startColumn=1,colStyle=NULL, colnamesStyle=NULL,rownamesStyle=NULL, showNA=FALSE, characterNA="", byrow=FALSE

前面讲过如何加载已有工作簿,这里以生成新excel工作簿为例,将数据写入文件中


> wb <- xlsx::createWorkbook()
> sheets <- getSheet()
# 新生成的工作簿没有sheet,系统提示:Workbook has no sheets!
> sheet <- createSheet(wb,sheetName = "newSheet1")

此时R内存中已经生成了一个工作簿,包含一个空的sheet工作表,通过addDataFrame()函数将数据写入sheet中.


> # 用上面生成的datas数据框对象,取前4行数据写入当前sheet对象中
> addDataFrame(data[1:4,],sheet,row.names = F)
> saveWorkbook(wb,file = "iris_new.xlsx")

==记得保存工作簿、记得保存工作簿、记得保存工作簿==

如果是在已有excel工作簿上操作,这里最好做一个判断,避免覆盖现有数据,造成不必要的麻烦。如果当前sheet的最后一行索引不等于零(说明有数据),则将新数据写到最后一行数据的下一行,同时不加入列名行(col.names = FALSE);如果为零则将数据直接添加到sheet中。


> # 用上面生成的datas数据框对象,取前4行数据写入当前sheet对象中
> if (sheet$getLastRowNum() != 0) {
+     addDataFrame(data[1:4,],sheet,row.names = F,col.names = F,startRow = sheet$getLastRowNum() + 2)
+    } else {
+     addDataFrame(data[1:4,],sheet,row.names = F)
+    }
+ }
> saveWorkbook(wb,file = "iris_new.xlsx")

至此,你应该知道如何在原有工作表基础上新增数据行了吧?多么方便!!

如果要增加新的sheet工作表,只需将sheet重新定义一个新的sheetName即可。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。如有错误或未考虑完全的地方,望不吝赐教。

--结束END--

本文标题: R语言之xlsx包读写Excel数据的操作

本文链接: https://www.lsjlt.com/news/122828.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • R语言之xlsx包读写Excel数据的操作
    感谢Adrian A. Drǎgulescu发布的xlsx包 xlsx包提供了必要的工具来与Excel 2007进行交互。用户可以阅读和编写xlsx,并可以通过设置数据格式、字体、颜...
    99+
    2024-04-02
  • 怎么在R语言中利用xlsx包读写Excel数据
    怎么在R语言中利用xlsx包读写Excel数据?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。下载安装xlsx(Rstudio会同步下载并安装rJava, xlsxjars两...
    99+
    2023-06-14
  • R语言开发之CSV文件的读写操作实现
    在R中,我们可以从存储在R环境外部的文件读取数据,还可以将数据写入由操作系统存储和访问的文件。这个csv文件应该存在于当前工作目录中,以方便R可以读取它, 当然,也可以设置自己的目录...
    99+
    2024-04-02
  • 用Python读写操作Excel数据!
    对比其它编程语言,我们都知道Python最大的优势是代码简单,有丰富的第三方开源库供开发者使用。伴随着近几年数据分析的热度,Python也成为最受欢迎的编程语言之一。而对于数据的读取和存储,对于普通人...
    99+
    2023-09-10
    python excel 开发语言
  • python操作excel之openpyxl模块读写xlsx格式使用方法详解
    openpyxl模块支持.xls和.xlsx格式的excel创建,但是只支持.xlsx格式的读取操作,不支持.xls的读取(可以使用xlrd模块来读取,写入操作也可使用xlwt模块)...
    99+
    2022-12-21
    python使用openpyxl模块读写xlsx格式 openpyxl创建新的excel openpyxl获取默认工作表 openpyxl删除工作表 openpyxl单元格操作
  • R语言实现二进制文件读写操作
    二进制文件是一个文件,其中包含仅以位和字节形式存储的信息(0和1),它们是不可读的,因为其中的字节转换为包含许多其他不可打印字符的字符和符号,随便我们尝试使用任何文本编辑器读取二进制...
    99+
    2024-04-02
  • R语言如何读取excel数据的简单方法
    本篇内容主要讲解“R语言如何读取excel数据的简单方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“R语言如何读取excel数据的简单方法”吧!安装库安装xlsxinstall.package...
    99+
    2023-06-08
  • R语言读取excel数据的方法(两行命令)
    安装库 安装xlsx install.packages("xlsx") 使用 library(xlsx) ray = read.xlsx('D:/Code/R/Data i...
    99+
    2024-04-02
  • R语言对Web数据操作实例
    许多网站提供数据供其用户使用。 例如,世界卫生组织(WHO)以CSV,txt和XML文件的形式提供健康和医疗信息的报告。 使用R语言程序,我们可以从这些网站以编程方式提取特定数据。 ...
    99+
    2024-04-02
  • R语言实现操作MySQL数据库
    用R语言做数据分析时,常常需要从多种数据源取数据,其中数据库是非常常见的数据源。用R操作MySQL数据库,可以说是数据分析师必备的技能了,本文介绍RMySQL包,可以在R语言中对数据...
    99+
    2024-04-02
  • python如何操作excel,在excel中读取和写入数据
    Excel是Microsoft为使用Windows和Apple Macintosh操作系统的电脑编写的一款电子表格软件。直观的界面、出色的计算功能和图表工具,再加上成功的市场营销,使Excel成为...
    99+
    2023-10-07
    python excel 开发语言
  • 怎么利用纯C语言对EXCEL进行读写操作
    本文小编为大家详细介绍“怎么利用纯C语言对EXCEL进行读写操作”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么利用纯C语言对EXCEL进行读写操作”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、写操作单纯...
    99+
    2023-07-02
  • R语言数据的输入和输出操作
    数据的载入 R本身已经提供了超过50个数据集,而在众多功能包中,默认的数据集被存放在datasets程序包中,通过函数data()k可以查看系统提供所有的数据包,同时可以通过函数li...
    99+
    2024-04-02
  • Go语言zip文件的读写操作
    目录创建 zip 归档文件读取 zip 归档文件Go语言的标准库提供了对几种压缩格式的支持,其中包括 gzip,因此 Go 程序可以无缝地读写 .gz 扩展名的 gzip 压缩文件或...
    99+
    2023-05-14
    Go语言zip读写 go读写ZIP文件
  • R语言变量级别的数据处理操作
    变量级别的数据处理无非是对变量的增删改查。 增 即增加新的变量 R语言中,增加一个新变量形式语句如下: 变量名 <- 表达式 表达式可以包含多种运算符和函数。常见运算符包括: ...
    99+
    2024-04-02
  • Go语言中JSON文件的读写操作
    目录写 JSON 文件读 JSON 文件JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成。它基于 ...
    99+
    2023-05-14
    Go语言JSON读写 Go语言读写JSON
  • Go语言中XML文件的读写操作
    目录写 XML 文件读 XML 文件XML(extensible Markup Language)格式被广泛用作一种数据交换格式,并且自成一种文件格式。与上一节介绍的 JSON 相比...
    99+
    2023-05-14
    Go语言XML文件读写 Go语言XML读写
  • R语言-进行数据的重新编码(recode)操作
    在分析数据时我们经常会遇到将变量值转换成其他的值的情况(如:将连续变量转成分类变量)这时就需要我们对原有数据进行重新编码。本文将介绍R软件中常用的三种重编吗方法: 1、使用逻辑判断式...
    99+
    2024-04-02
  • Go语言学习笔记之文件读写操作详解
    目录文件写文件读小结文件操作比较多,分为几篇来写吧。首先是文件的读写,在平时的工程化操作中使用最多。 文件写 样例代码如下 package main import ( "...
    99+
    2024-04-02
  • R语言之左连接的三种实现操作
    数据处理中经常遇到表连接问题,本次介绍R语言中三种左连接方法,这三种是等价的,不过会有时间快慢问题,斟酌使用。 法一: > data0 <- merge(a,c,al...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作