R语言- data.table包加速大型数据集的加载和运算效率用法示例

简介: 本文根据个人使用经验和博客参考,总结分享了在R语言中使用data.table包来提升大型数据集处理效率的用法示例,以供参考

R语言具有较强的数据分析能力,但作为一种解释型语言在面对较大型数据集 时,使用基础软件包的处理效率会变得非常低下。为了解决处理较大数据集的问题,R语言社区涌现了一系列数据处理的包,如data.table、dplyr等。其中,data.table 包是一个非常实用的包,它提供了一组高效的数据处理函数,可以方便地处理大型数据集。

R语言data.table包是自带包data.frame的升级版,用于数据框格式数据的处理,最大的特点是 。它内部处理的步骤进行了程序上的优化,使用多线程,还有很多C编写的函数,大大加快数据运行速度。尤其当对一两百万甚至更大数据集进行修改或运算时,由于data.table直接对数据本身做运算,不创建副本,因此相较于基本的data.frame格式,data.table在面对大型数据集时,进行聚合排序以及分组运算的性能非常高 !

$\color{red}{注意:}$data.table和data.frame的主要格式区别是data.table格式没有行名,但可以通过设置键来指定索引列,根据索引列的值进行数据索引。

本文主要整理了下data.table对象的一些常用操作方法

1、 data.table的一般语法格式

data.table数据框结构处理语法 DT[ i , j , by]

  • i 决定显示的行,可以是整型,可以是字符,可以是表达式,
  • j 是对数据框进行求值,决定显示的列,
  • by 对数据进行指定分组,除了by ,也可以添加其它的一系列参数:keyby,with,nomatch,mult,rollollends,which,.SDcols,on等

2、读写文件

读取文件的4种便捷操作:

data.table提供了基于C语言编写 fread()方法,能够非常高效地读取大型数据集,以下是用法示例:

  • ① - nrows 参数指定读取多少行
    fread("fileName", sep="\t",nrows = 10)
  • ② - select 参数选择要导入的列或drop参数进行反向选择
    fread("fileName", sep="\t",select = c("column_1", "column_2", 6 ))
    fread("fileName", sep="\t",drop = c("column_3", "column_4", 5 ))
  • ③- *colClasses 参数在加载文件时完成列属性指定
    fread("fileName", sep="\t", colClasses = c("column_1" = "numeric"))
  • ④ - cmd 参数配合使用Linux命令读取zip文件
    fread(cmd = 'unzip -cq fileName.zip' ,sep="\t").
    写出文件:
    fwrite(out,"fileName",col.names=T,row.names=F,sep="\t",quote=F)
    如果是写出一个字符串或vector形式的内容的话,需要提前转为list数据结构,不然会报异常:
    Error in fwrite(unique(unique(DT[, y])), file = paste0(sampletag, "_arealst.tsv")) : 不是所有的is.list(x)都是TRUE
    $\rightarrow$ 正确处理方式fwrite(list("a long string"),file = "here.txt")

3、数据框对象转换

as.data.table和setDT也可用于转换list和data.frame为data.table对象,不同的是前者会完全复制原对象,然后进行转换,而setDT方法以传地址的方式直接修改原对象,不拷贝直接操作原数据集,因此前者更加的耗时和耗内存。
dt <- setDT(df,keep.rownames = T, key = "rn")

  • keep.rownames 参数保留原data.frame的行名,默认新建一列"rn"存放原data.frame的行名
  • key 参数设置dt对象的索引列,列的值可以重复。键值设置还可以通过 setkey(df,"rn")

4、常用对象操作方法示例

image.png

(1) 数据集的行记录过滤
DT = data.table(x=rep(c( "b", "a", "c" ),each=3), y=c(1,3,6), v=1:9)
DT[2] #取第二行
DT[2:3] #取第二到第三行
DT[order(x)] #将DT按照X列排序,简化操作,另外排序也可以setkey(DT,x),出来的DT就已经是按照x列排序的了。用haskey(DT)判断DT是否已经设置了key,可以设置多个列作为key
DT[y 2] # DT$y 2的行
DT[!2:4] #除了2到4行剩余的行
DT[ "a" ,on= "x" ] #on 参数,在x列取出值为"a"的行
DT[.( "a" ), on= "x" ] #和上面一样.()有类似与c()的作用
DT[ "a" , on=.( x )] #和上面一样
DT[ x == "a" ] # 和上面一样,和使用on一样,都是使用二分查找法,所以它们速度比用data.frame的快。
DT[x! = "b" | y != 3 ] #x列不等于 b 或者y列不等于3的行
DT[.( "b" , 3), on=.(x, v)] #取DT的x,v列上x= b ,v=3的行
(2) 数据框的求值操作

数据运算包括输出sum,max,min,tail等基本函数的计算结果,还可以用n输出第n列,.N(总列数,直接在j输入.N取最后一列),:=(直接在data.table上新建列),.SD(SubDadaColums)输出子集,.SD[n]输出子集的第n列。

DT = data.table(x=rep(c( "b", "a", "c" ),each=3), y=c(1,3,6), v=1:9)
DT[,y] #返回vector格式的y列的值
DT[,.(y)] #返回data.table格式的y列的值
DT[, sum(y)] #对y列求和
DT[, .(sv=sum(v))] #对y列求和,输出sv列,列中的内容就是sum(v)
DT[, .(sum(y)), by=x] # 对x列进行分组后对各分组y列求总和
DT[, sum(y), keyby=x] #对x列进行分组后对各分组y列求和,并且结果按照x排序
DT[, sum(y), by=x][order(x)] #和上面一样,采取data.table的链接符合表达式
DT[v==1, sum(y), by=x] #对v列进行分组后,取各组中v==1的行出来,各组分别对定义的行中的y求和
DT[, .N, by=x] #用by对DT 用x分组后,取每个分组的总行数
DT[, .SD, .SDcols=x:y] #用.SDcols 定义SubDadaColums(子列数据),这里取出x到y之间的列作为子集,然后.SD 输出所有子集
DT[, .SD[1], by = x] #抽提x列分组后每个子集的第一行
DT[, .SD[.N], by = x] #抽提x列分组后每个子集的最后一行
DT[2:5, cat(y,"\n" )] #直接在j 用cat函数,输出2到5列的y值
DT[, plot(a,b), by=x] #直接在j用plot函数画图,对于每个x的分组画一张图
DT[, m:=mean(v), by=x] #对DT按x列分组,直接在DT上再添加一列m,m的内容是mean(v),直接修改并且不输出到屏幕上
DT[, m:=mean(v), by=x] [] #加[]将结果输出到屏幕上
DT[,c( m , n ):=list(mean(v),min(v)), by=x][] # 按x分组后同时添加m,n 两列,内容是分别是mean(v)和min(v),并且输出到屏幕
DT[,.(seq = min(y):max(v)), by=x] #输出seq列,内容是min(a)到max(b)
DT[, c(.(y=max(y)), lapply(.SD, min)), by=x, .SDcols=y:v] #对DT取y:v之间的列,按x分组,输出max(y),对y到v之间的列
(3)删除一列

DT[,x := NULL]

(4)列属性转换

DT[,b := as.integer(y)]
其它有如as.integer(), as.numeric(),as.character(), as.Date()等函数

(5)根据多列的值进行去重

unique(DT, by = c("x","y"))

(6)根据列重排序

setorder(DT, x, -y) #x列升序,y列降序(-)

(7)配合使用lapply示例

对DT根据x列进行分组,子集保留"v", "y"两列,对每个自己的这两列求取均值:
DT[, lapply(.SD, mean), .SDcols = c("v", "y"),by = x ]

(8)分组计数

DT[, c := .N, by = x]

(9) 为特定的单元格赋值

将DT第五行的"y", "v"两列的值替换第二行"y", "v"的值
DT[2, c("y", "v") := as.list(DT[5, c(y, v)])]
直接修改第一行x列的单元格值为MMM
DT[1,x := "MMM"]

(10) 数据框链接

内联接,nomatch=0表示不返回不匹配的行,nomatch=NA表示以NA返回不匹配的值
DT[X, on= .("x","y") , nomatch=0]
只通过一列公共列进行链接的话可以写成:
DT[X, on= "x" , nomatch=0]DT[X, on= .(x), nomatch=0]

(11) 内容搜索返回行号

设置参数which =NA
DT["a",on = .(x), which = TRUE ] #在x列匹配值为"a"的记录的行号

(12) 随机抽取n行

DT[sample(.N,n)]
DT[sample(.N,0.5.N)] #随机抽取全数据集50%的行

(13) 通过A,B列分组,保留C列中出现频率最高的值完成去重过程

DT[, .SD[which.max(table(C))], by = list(A,B)]


Reference

Rdatatable/data.table: R's data.table package extends data.frame: (github.com)
R语言数据分析利器data.table包 —— 数据框结构处理精讲-汗血宝马 (caotama.com)

目录
相关文章
|
6月前
|
机器学习/深度学习 数据可视化 Python
R语言使用逻辑回归Logistic、单因素方差分析anova、异常点分析和可视化分类iris鸢尾花数据集|数据分享
R语言使用逻辑回归Logistic、单因素方差分析anova、异常点分析和可视化分类iris鸢尾花数据集|数据分享
|
6月前
|
机器学习/深度学习 数据可视化 数据处理
数据分享|R语言逻辑回归(Logistic Regression)、回归决策树、随机森林信用卡违约分析信贷数据集
数据分享|R语言逻辑回归(Logistic Regression)、回归决策树、随机森林信用卡违约分析信贷数据集
|
3月前
|
存储 数据采集 数据处理
R语言数据变换:使用tidyr包进行高效数据整形的探索
【8月更文挑战第29天】`tidyr`包为R语言的数据整形提供了强大的工具。通过`pivot_longer()`、`pivot_wider()`、`separate()`和`unite()`等函数,我们可以轻松地将数据从一种格式转换为另一种格式,以满足不同的分析需求。掌握这些函数的使用,将大大提高我们处理和分析数据的效率。
|
22天前
|
数据挖掘 C语言 C++
R语言是一种强大的统计分析工具,提供了丰富的函数和包用于时间序列分析。
【10月更文挑战第21天】时间序列分析是一种重要的数据分析方法,广泛应用于经济学、金融学、气象学、生态学等领域。R语言是一种强大的统计分析工具,提供了丰富的函数和包用于时间序列分析。本文将介绍使用R语言进行时间序列分析的基本概念、方法和实例,帮助读者掌握R语言在时间序列分析中的应用。
40 3
|
6月前
【R语言实战】——fGARCH包在金融时序上的模拟应用
【R语言实战】——fGARCH包在金融时序上的模拟应用
|
6月前
|
存储 算法 Windows
课程视频|R语言bnlearn包:贝叶斯网络的构造及参数学习的原理和实例(下)
课程视频|R语言bnlearn包:贝叶斯网络的构造及参数学习的原理和实例
|
6月前
|
算法 数据可视化 数据挖掘
课程视频|R语言bnlearn包:贝叶斯网络的构造及参数学习的原理和实例(上)
课程视频|R语言bnlearn包:贝叶斯网络的构造及参数学习的原理和实例
|
6月前
|
SQL 算法 数据可视化
R语言k-prototype聚类新能源汽车行业上市公司分析混合型数据集(上)
R语言k-prototype聚类新能源汽车行业上市公司分析混合型数据集
|
6月前
|
数据挖掘 开发工具 Android开发
R语言对git安卓包分类统计、聚类、复杂网络可视化分析
R语言对git安卓包分类统计、聚类、复杂网络可视化分析
|
6月前
|
存储
【视频】R语言中的分布滞后非线性模型(DLNM)与发病率,死亡率和空气污染示例
【视频】R语言中的分布滞后非线性模型(DLNM)与发病率,死亡率和空气污染示例