Data.table学习
R语言data.table包是自带包data.frame的升级版,用于数据框格式数据的处理,最大的特点快
和data.frame的高度兼容
library(data.table)
DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9)
DT
DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9)
DT
##
x y v
## 1: b 1 1
## 2: b 3 2
## 3: b 6 3
## 4: a 1 4
## 5: a 3 5
## 6: a 6 6
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
## 1: b 1 1
## 2: b 3 2
## 3: b 6 3
## 4: a 1 4
## 5: a 3 5
## 6: a 6 6
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
str(DT)
##
Classes 'data.table' and 'data.frame': 9 obs. of 3 variables:
## $ x: chr "b" "b" "b" "a" ...
## $ y: num 1 3 6 1 3 6 1 3 6
## $ v: int 1 2 3 4 5 6 7 8 9
## - attr(*, ".internal.selfref")=<externalptr>
## $ x: chr "b" "b" "b" "a" ...
## $ y: num 1 3 6 1 3 6 1 3 6
## $ v: int 1 2 3 4 5 6 7 8 9
## - attr(*, ".internal.selfref")=<externalptr>
DF
=
data.frame(x=rep(c("b","a","c"),each=3),
y=c(1,3,6),
v=1:9)
可见它是属于data.table和data.frame类,并且取列,维数,都可以采用data.frame的方法。
##
[1] TRUE
##
[1] TRUE
##
[1] TRUE
不过data.frame默认将非数字转化为因子;而data.table
会将非数字转化为字符
DF[1,1]
##
[1] b
## Levels: a b c
## Levels: a b c
DT[1,1]
##
x
## 1: b
## 1: b
data.table常用的函数
as.data.table(x, keep.rownames=FALSE,
...) 将一个R对象转化为data.table,R可以时矢量,列表,data.frame等,keep.rownames决定是否保留行名或者列表名,默认FALSE,如果TRUE,将行名存在"rn"行中,keep.rownames="id",行名保存在"id"行中。
DF
=
data.frame(x=rep(c("b","a","c"),each=3),
y=c(1,3,6),
v=1:9)
#新建data.frame
DF
DT=as.data.table(DF,keep.rownames=TRUE)
DT=as.data.table(DF,keep.rownames=TRUE)
setDT(x, keep.rownames=FALSE,
key=NULL,check.names=FALSE)把一个R对象转化为data.table,比as.data.table快,因为以传地址的方式直接修改原对象,没有拷贝
copy(x) 深度拷贝一个data.table,x即data.table对象。data.table为了加快速度,会直接在对象地址修改,因此如果需要就要在修改前copy,直接修改的命令有:=添加一列,set系列命令比如下面提到的setattr,setnames,setorder等;当使用dt_names
=
names(DT)的时候,修改dt_names会修改原data.table的列名,如果不想被修改,这个时候应copy原data.table,也可以使用dt_names
<- copy(names(DT))直接copy列名,这样不必copy整个data.table。
#kDT时DT的一个copy
kDT <- copy(DT)
kDT <- copy(DT)
rowid(...,
prefix=NULL)产生unique的id,prefix参数在id前面加前缀
rowid(DT$x,prefix
=
"c")
##
[1] "c1" "c2" "c3" "c1" "c2"
"c3" "c1" "c2" "c3"
setattr 设置DT的属性,setattr(x,name,value)
x时data.table,list或者data.frame,而name时属性名,value时属性值,setnames(x,old,new),设置x的列名,old是旧列名或者数字位置,new是新列名
setnames(kDT,c('x','y'),c('a','b'))
kDT
kDT
##
rn a b v
## 1: 1 b 1 1
## 2: 2 b 3 2
## 3: 3 b 6 3
## 4: 4 a 1 4
## 5: 5 a 3 5
## 6: 6 a 6 6
## 7: 7 c 1 7
## 8: 8 c 3 8
## 9: 9 c 6 9
## 1: 1 b 1 1
## 2: 2 b 3 2
## 3: 3 b 6 3
## 4: 4 a 1 4
## 5: 5 a 3 5
## 6: 6 a 6 6
## 7: 7 c 1 7
## 8: 8 c 3 8
## 9: 9 c 6 9
set(DT,rownum,colnum,value)直接修改某个位置的值,rownum行号,colnum,列号,行号列号推荐使用整型,保证最快速度,方法是在数字后面加L,比如1L,value是需要赋予的值。比:=还快,通常和循环配合使用
kDT
<-
copy(DT)
for(i in 1:nrow(kDT)){
set(kDT,i,1L,'a')
}
for(i in 1:nrow(kDT)){
set(kDT,i,1L,'a')
}
fread input输入的文件,或者字符串(至少有一个"");
sep列之间的分隔符;
sep2,分隔符内再分隔的分隔符,功能还没有应用;
nrow,读取的行数,默认-l全部,nrow=0仅仅返回列名;
header第一行是否是列名;
na.strings,对NA的解释;
file文件路径,再确保没有执行shell命令时很有用,也可以在input参数输入;
stringsASFactors是否转化字符串为因子,
verbose,是否交互和报告运行时间;
autostart,机器可读这个区域任何行号,默认1L,如果这行是空,就读下一行;
skip跳过读取的行数,为1则从第二行开始读,设置了这个选项,就会自动忽略autostart选项,也可以是一个字符,skip="string",那么会从包含该字符的行开始读;
select,需要保留的列名或者列号,不要其它的;
drop,需要取掉的列名或者列号,要其它的;
colClasses,类字符矢量,用于罕见的覆盖而不是常规使用,只会使一列变为更高的类型,不能降低类型;
integer64,读如64位的整型数;
dec,小数分隔符,默认"."不然就是","
col.names,给列名,默认试用header或者探测到的,不然就是V+列号;
encoding,默认"unknown",其它可能"UTF-8"或者"Latin-1",不是用来重新编码的,而是允许处理的字符串在本机编码;
quote,默认""",如果以双引开头,fread强有力的处理里面的引号,如果失败了就会用其它尝试,如果设置quote="",默认引号不可用
strip.white,默认TRUE,删除结尾空白符,如果FALSE,只取掉header的结尾空白符;
fill,默认FALSE,如果TRUE,不等长的区域可以自动填上,利于文件顺利读入;
blank.lines.skip,默认FALSE,如果TRUE,跳过空白行
key,设置key,用一个或多个列名,会传递给setkey
showProgress,TRUE会显示脚本进程,R层次的C代码
data.table,TRUE返回data.table,FALSE返回data.frame
fread(input,
sep="auto",
sep2="auto",
nrows=-1L,
header="auto",
na.strings="NA",
file,
stringsAsFactors=FALSE, verbose=getOption("datatable.verbose"), autostart=1L,
skip=0L, select=NULL, drop=NULL, colClasses=NULL,
integer64=getOption("datatable.integer64"),
# default: "integer64"
dec=if (sep!=".") "." else ",", col.names,
check.names=FALSE, encoding="unknown", quote="\"",
strip.white=TRUE, fill=FALSE, blank.lines.skip=FALSE, key=NULL,
showProgress=getOption("datatable.showProgress"), # default: TRUE
data.table=getOption("datatable.fread.datatable") # default: TRUE
)
stringsAsFactors=FALSE, verbose=getOption("datatable.verbose"), autostart=1L,
skip=0L, select=NULL, drop=NULL, colClasses=NULL,
integer64=getOption("datatable.integer64"),
# default: "integer64"
dec=if (sep!=".") "." else ",", col.names,
check.names=FALSE, encoding="unknown", quote="\"",
strip.white=TRUE, fill=FALSE, blank.lines.skip=FALSE, key=NULL,
showProgress=getOption("datatable.showProgress"), # default: TRUE
data.table=getOption("datatable.fread.datatable") # default: TRUE
)
fwrite
,具有相同长度的列表,比如data.frame和data.table等;
file,输出文件名,""意味着直接输出到操作台;
append,如果TRUE,在原文件的后面添加;
quote,如果"auto",因子和列名只有在他们需要的时候才会被加上双引号,例如该部分包括分隔符,或者以""结尾的一行,或者双引号它自己,如果FALSE,那么区域不会加上双引号,如果TRUE,就像写入CSV文件一样,除了数字,其它都加上双引号;
sep,列之间的分隔符;
sep2,对于是list的一列,写出去时list成员间以sep2分隔,它们是处于一列之内,然后内部再用字符分开;
eol,行分隔符,默认Windows是"",其它的是"";
na,na值的表示,默认"";
dec,小数点的表示,默认".";
row.names,是否写出行名,因为data.table没有行名,所以默认FALSE;
col.names
,是否写出列名,默认TRUE,如果没有定义,并且append=TRUE和文件存在,那么就会默认使用FALSE;
qmethod,怎样处理双引号,"escape",类似于C风格,用反斜杠逃避双引,“double",默认,双引号成对;
logicalAsInt,逻辑值作为数字写出还是作为FALSE和TRUE写出;
dateTimeAS, 决定
Date/IDate,ITime和POSIXct的写出,"ISO"默认,-2016-09-12,
18:12:16和2016-09-12T18:12:16.999999Z;"squash",-20160912,181216和20160912181216999;"epoch",-17056,65536和1473703936;"write.csv",就像write.csv一样写入时间,仅仅对POSIXct有影响,as.character将digits.secs转化字符并通过R内部UTC转回本地时间。前面三个选项都是用新的特定C代码写的,较快
buffMB,每个核心给的缓冲大小,在1到1024之间,默认80MB
nThread,用的核心数。
showProgress,在工作台显示进程,当用file==""时,自动忽略此参数
verbose,是否交互和报告时间
fwrite(x,
file
=
"",
append
=
FALSE,
quote
=
"auto",
sep = ",", sep2 = c("","|",""),
eol = if (.Platform$OS.type=="windows") "\r\n" else "\n",
na = "", dec = ".", row.names = FALSE, col.names = TRUE,
qmethod = c("double","escape"),
logicalAsInt = FALSE, dateTimeAs = c("ISO","squash","epoch","write.csv"),
buffMB = 8L, nThread = getDTthreads(),
showProgress = getOption("datatable.showProgress"),
verbose = getOption("datatable.verbose"))
sep = ",", sep2 = c("","|",""),
eol = if (.Platform$OS.type=="windows") "\r\n" else "\n",
na = "", dec = ".", row.names = FALSE, col.names = TRUE,
qmethod = c("double","escape"),
logicalAsInt = FALSE, dateTimeAs = c("ISO","squash","epoch","write.csv"),
buffMB = 8L, nThread = getDTthreads(),
showProgress = getOption("datatable.showProgress"),
verbose = getOption("datatable.verbose"))
data.table数据框结构处理语法
data.table[ i , j , by] i
决定显示的行,可以是整型,可以是字符,可以是表达式,j
是对数据框进行求值,决定显示的列,by对数据进行指定分组,除了by
,也可以添加其它的一系列参数:keyby,with,nomatch,mult,rollollends,which,.SDcols,on。
#新建data.table对象DT
DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9)
#取第二行
DT[2]
DT = data.table(x=rep(c("b","a","c"),each=3), y=c(1,3,6), v=1:9)
#取第二行
DT[2]
##
x y v
## 1: b 3 2
## 1: b 3 2
#取第二到第三行
DT[2:3]
DT[2:3]
##
x y v
## 1: b 3 2
## 2: b 6 3
## 1: b 3 2
## 2: b 6 3
#将DT按照X列排序,简化操作,另外排序也可以setkey(DT,x),出来的DT就已经是按照x列排序的了。用haskey(DT)判断DT是否已经设置了key,可以设置多个列作为key
DT[order(x)]
DT[order(x)]
##
x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
## 4: b 1 1
## 5: b 3 2
## 6: b 6 3
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
## 4: b 1 1
## 5: b 3 2
## 6: b 6 3
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
#
DT$y>2的行
DT[y>2]
DT[y>2]
##
x y v
## 1: b 3 2
## 2: b 6 3
## 3: a 3 5
## 4: a 6 6
## 5: c 3 8
## 6: c 6 9
## 1: b 3 2
## 2: b 6 3
## 3: a 3 5
## 4: a 6 6
## 5: c 3 8
## 6: c 6 9
#除了2到4行剩余的行
DT[!2:4]
DT[!2:4]
##
x y v
## 1: b 1 1
## 2: a 3 5
## 3: a 6 6
## 4: c 1 7
## 5: c 3 8
## 6: c 6 9
## 1: b 1 1
## 2: a 3 5
## 3: a 6 6
## 4: c 1 7
## 5: c 3 8
## 6: c 6 9
#on
参数,DT[D,on=c("x","y")]取DT上"x","y"列上与D上的列相关联的行。比如此例取出DT
中
X
列为"a"的行。on参数的第一列必须是DT的第一列
DT["a",on="x"]
DT["a",on="x"]
##
x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
#和上面一样.()有类似与c()的作用
DT[.("a"),on=.(x)]
DT[.("a"),on=.(x)]
##
x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
#和上面一样
DT["a",on=.(x)]
DT["a",on=.(x)]
##
x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
#
和上面一样,和使用on一样,都是使用二分查找法,所以它们速度比用data.frame的快。也可以用setkey之后的DT,输入DT["a"]或者DT["a",on=.(x)]如果有几个key的话推荐用on
DT[x=="a"]
DT[x=="a"]
##
x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
#x列不等于"b"或者y列不等于3的行
DT[x!="b"|y!=3]
DT[x!="b"|y!=3]
##
x y v
## 1: b 1 1
## 2: b 6 3
## 3: a 1 4
## 4: a 3 5
## 5: a 6 6
## 6: c 1 7
## 7: c 3 8
## 8: c 6 9
## 1: b 1 1
## 2: b 6 3
## 3: a 1 4
## 4: a 3 5
## 5: a 6 6
## 6: c 1 7
## 7: c 3 8
## 8: c 6 9
#取DT的x,v列上x="b",v=3的行
DT[.("b",3),on=.(x,v)]
DT[.("b",3),on=.(x,v)]
##
x y v
## 1: b 6 3
## 1: b 6 3
j 对数据框进行求值输出
j
参数对数据进行运算,比如sum,max,min,tail等基本函数,输出基本函数的计算结果,还可以用n输出第n列,.N(总列数,直接在j输入.N取最后一列),:=(直接在data.table上添加列,没有copy过程,所以快,有需要的话注意备份),.SD输出子集,.SD[n]输出子集的第n列,DT[,.(a
= .(), b = .())] 输出一个a、b列的数据框,.()就是要输入的a、b列的内容,还可以将一系列处理放入大括号,如{tmp
<- mean(y);.(a = a-tmp, b = b-tmp)}
#返回y列,矢量
DT[,y]
DT[,y]
##
[1] 1 3 6 1 3 6 1 3 6
#返回y列,返回data.table
DT[,.(y)]
DT[,.(y)]
##
y
## 1: 1
## 2: 3
## 3: 6
## 4: 1
## 5: 3
## 6: 6
## 7: 1
## 8: 3
## 9: 6
## 1: 1
## 2: 3
## 3: 6
## 4: 1
## 5: 3
## 6: 6
## 7: 1
## 8: 3
## 9: 6
#对y列求和
DT[,sum(y)]
DT[,sum(y)]
##
[1] 30
#对y列求和,输出sv列,列中的内容就是sum(v)
DT[,.(sv=sum(y))]
DT[,.(sv=sum(y))]
##
sv
## 1: 30
## 1: 30
#
对x列进行分组后对各分组y列求总和
DT[,.(sum(y)),by=x]
DT[,.(sum(y)),by=x]
##
x V1
## 1: b 10
## 2: a 10
## 3: c 10
## 1: b 10
## 2: a 10
## 3: c 10
#对x列进行分组后对各分组y列求和,并且结果按照x排序
DT[,sum(y),keyby=x]
DT[,sum(y),keyby=x]
##
x V1
## 1: a 10
## 2: b 10
## 3: c 10
## 1: a 10
## 2: b 10
## 3: c 10
#和上面一样,采取data.table的链接符合表达式
DT[,sum(y),by=x][order(x)]
DT[,sum(y),by=x][order(x)]
##
x V1
## 1: a 10
## 2: b 10
## 3: c 10
## 1: a 10
## 2: b 10
## 3: c 10
#对v列进行分组后,取各组中v>1的行出来,各组分别对定义的行中的y求和
DT[v>1,sum(y),by=v]
DT[v>1,sum(y),by=v]
##
v V1
## 1: 2 3
## 2: 3 6
## 3: 4 1
## 4: 5 3
## 5: 6 6
## 6: 7 1
## 7: 8 3
## 8: 9 6
## 1: 2 3
## 2: 3 6
## 3: 4 1
## 4: 5 3
## 5: 6 6
## 6: 7 1
## 7: 8 3
## 8: 9 6
#用by对DT
用x分组后,取每个分组的总列数
DT[,.N,by=x]
DT[,.N,by=x]
##
x N
## 1: b 3
## 2: a 3
## 3: c 3
## 1: b 3
## 2: a 3
## 3: c 3
#用.SDcols
定义SubDadaColums(子列数据),这里取出x到之间的列作为子集,然后.SD
输出所有子集
DT[,.SD,.SDcols=x:y]
DT[,.SD,.SDcols=x:y]
##
x y
## 1: b 1
## 2: b 3
## 3: b 6
## 4: a 1
## 5: a 3
## 6: a 6
## 7: c 1
## 8: c 3
## 9: c 6
## 1: b 1
## 2: b 3
## 3: b 6
## 4: a 1
## 5: a 3
## 6: a 6
## 7: c 1
## 8: c 3
## 9: c 6
#直接在j
用cat函数,输出2到5列的y值
DT[2:5,cat(y,"\n")]
DT[2:5,cat(y,"\n")]
##
3 6 1 3
##
NULL
#直接在j用plot函数画图,对于每个x的分组画一张图
DT[,plot(y,v),by=x]
DT[,plot(y,v),by=x]
##
Empty data.table (0 rows) of 1 col: x
#对DT按x列分组,直接在DT上再添加一列m,m的内容是mean(v),直接修改并且不输出到屏幕上
DT[,m:=mean(v),by=x]
#加[]将结果输出到屏幕上
DT[,m:=mean(v),by=x][]
DT[,m:=mean(v),by=x]
#加[]将结果输出到屏幕上
DT[,m:=mean(v),by=x][]
##
x y v m
## 1: b 1 1 2
## 2: b 3 2 2
## 3: b 6 3 2
## 4: a 1 4 5
## 5: a 3 5 5
## 6: a 6 6 5
## 7: c 1 7 8
## 8: c 3 8 8
## 9: c 6 9 8
## 1: b 1 1 2
## 2: b 3 2 2
## 3: b 6 3 2
## 4: a 1 4 5
## 5: a 3 5 5
## 6: a 6 6 5
## 7: c 1 7 8
## 8: c 3 8 8
## 9: c 6 9 8
#
按x分组后同时添加m,n
两列,内容是分别是mean(v)和min(v),并且输出到屏幕
DT[,c("m","n"):=list(mean(v),min(v)),by=x][]
DT[,c("m","n"):=list(mean(v),min(v)),by=x][]
##
x y v m n
## 1: b 1 1 2 1
## 2: b 3 2 2 1
## 3: b 6 3 2 1
## 4: a 1 4 5 4
## 5: a 3 5 5 4
## 6: a 6 6 5 4
## 7: c 1 7 8 7
## 8: c 3 8 8 7
## 9: c 6 9 8 7
## 1: b 1 1 2 1
## 2: b 3 2 2 1
## 3: b 6 3 2 1
## 4: a 1 4 5 4
## 5: a 3 5 5 4
## 6: a 6 6 5 4
## 7: c 1 7 8 7
## 8: c 3 8 8 7
## 9: c 6 9 8 7
#内容和上面一样,另外的写法
DT[,":="(m=mean(v),n=min(v)),by=x][]
DT[,":="(m=mean(v),n=min(v)),by=x][]
##
x y v m n
## 1: b 1 1 2 1
## 2: b 3 2 2 1
## 3: b 6 3 2 1
## 4: a 1 4 5 4
## 5: a 3 5 5 4
## 6: a 6 6 5 4
## 7: c 1 7 8 7
## 8: c 3 8 8 7
## 9: c 6 9 8 7
## 1: b 1 1 2 1
## 2: b 3 2 2 1
## 3: b 6 3 2 1
## 4: a 1 4 5 4
## 5: a 3 5 5 4
## 6: a 6 6 5 4
## 7: c 1 7 8 7
## 8: c 3 8 8 7
## 9: c 6 9 8 7
#输出seq列,内容是min(a)到max(b)
DT[,(seq=min(y):max(v)),by=x]
DT[,(seq=min(y):max(v)),by=x]
##
x V1
## 1: b 1
## 2: b 2
## 3: b 3
## 4: a 1
## 5: a 2
## 6: a 3
## 7: a 4
## 8: a 5
## 9: a 6
## 10: c 1
## 11: c 2
## 12: c 3
## 13: c 4
## 14: c 5
## 15: c 6
## 16: c 7
## 17: c 8
## 18: c 9
## 1: b 1
## 2: b 2
## 3: b 3
## 4: a 1
## 5: a 2
## 6: a 3
## 7: a 4
## 8: a 5
## 9: a 6
## 10: c 1
## 11: c 2
## 12: c 3
## 13: c 4
## 14: c 5
## 15: c 6
## 16: c 7
## 17: c 8
## 18: c 9
#对DT取y:v之间的列,按x分组,输出max(y),对y到v之间的列每列求最小值输出。
DT[,c(.(y=max(y)),lapply(.SD,min)),by=x,.SDcols=y:v]
DT[,c(.(y=max(y)),lapply(.SD,min)),by=x,.SDcols=y:v]
##
x y y v
## 1: b 6 1 1
## 2: a 6 1 4
## 3: c 6 1 7
## 1: b 6 1 1
## 2: a 6 1 4
## 3: c 6 1 7
by,on,with等参数
by对数据进行分组
DT
<-
data.table(x=rep(c("b","a","c"),each=3),y=c(1,3,6),v=1:9)
DT
DT
##
x y v
## 1: b 1 1
## 2: b 3 2
## 3: b 6 3
## 4: a 1 4
## 5: a 3 5
## 6: a 6 6
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
## 1: b 1 1
## 2: b 3 2
## 3: b 6 3
## 4: a 1 4
## 5: a 3 5
## 6: a 6 6
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
DT[,.(sum(y)),by=x]
##
x V1
## 1: b 10
## 2: a 10
## 3: c 10
## 1: b 10
## 2: a 10
## 3: c 10
on
DT[D,on=c("x","y")]取DT上"x","y"列上与D上的列相关联的行
X=data.table(x=c("c","b"),v=8:7,foo=c(4,2))
#左联接
DT[X,on="x"]
#左联接
DT[X,on="x"]
##
x y v i.v foo
## 1: c 1 7 8 4
## 2: c 3 8 8 4
## 3: c 6 9 8 4
## 4: b 1 1 7 2
## 5: b 3 2 7 2
## 6: b 6 3 7 2
## 1: c 1 7 8 4
## 2: c 3 8 8 4
## 3: c 6 9 8 4
## 4: b 1 1 7 2
## 5: b 3 2 7 2
## 6: b 6 3 7 2
#右联接
X[DT,on="x"]
X[DT,on="x"]
##
x v foo y i.v
## 1: b 7 2 1 1
## 2: b 7 2 3 2
## 3: b 7 2 6 3
## 4: a NA NA 1 4
## 5: a NA NA 3 5
## 6: a NA NA 6 6
## 7: c 8 4 1 7
## 8: c 8 4 3 8
## 9: c 8 4 6 9
## 1: b 7 2 1 1
## 2: b 7 2 3 2
## 3: b 7 2 6 3
## 4: a NA NA 1 4
## 5: a NA NA 3 5
## 6: a NA NA 6 6
## 7: c 8 4 1 7
## 8: c 8 4 3 8
## 9: c 8 4 6 9
#内联接,nomatch=0表示不返回不匹配的行,nomatch=NA表示以NA返回不匹配的值
DT[X,on="x",nomatch=0]
DT[X,on="x",nomatch=0]
##
x y v i.v foo
## 1: c 1 7 8 4
## 2: c 3 8 8 4
## 3: c 6 9 8 4
## 4: b 1 1 7 2
## 5: b 3 2 7 2
## 6: b 6 3 7 2
## 1: c 1 7 8 4
## 2: c 3 8 8 4
## 3: c 6 9 8 4
## 4: b 1 1 7 2
## 5: b 3 2 7 2
## 6: b 6 3 7 2
with默认是TRUE,列名能够当作变量使用,即x相当于DT$"x",当是FALSE时,列名仅仅作为字符串,可以用传统data.frame方法并且返回data.table,x[,
cols, with=FALSE] 和x[, .SD,
.SDcols=cols]一样
DT[,"x",with=F]
##
x
## 1: b
## 2: b
## 3: b
## 4: a
## 5: a
## 6: a
## 7: c
## 8: c
## 9: c
## 1: b
## 2: b
## 3: b
## 4: a
## 5: a
## 6: a
## 7: c
## 8: c
## 9: c
mult当有i
中匹配到的有多行时,mult控制返回的行,"all"返回全部(默认),"first",返回第一行,"last"返回最后一行
DT["a",on="x",mult="last"]
##
x y v
## 1: a 6 6
## 1: a 6 6
roll当i中全部行匹配只有某一行不匹配时,填充该行空白,+Inf(或者TRUE)用上一行的值填充,-Inf用下一行的值填充,输入某数字时,表示能够填充的距离,near用最近的行填充
rollends填充首尾不匹配的行,TRUE填充,FALSE不填充,与roll一同使用
DT[letters[1:4],on="x",roll=T]
##
x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
## 4: b 1 1
## 5: b 3 2
## 6: b 6 3
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
## 10: d 6 9
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
## 4: b 1 1
## 5: b 3 2
## 6: b 6 3
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
## 10: d 6 9
DT[letters[1:4],on="x",roll=Inf,rollends=F]
##
x y v
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
## 4: b 1 1
## 5: b 3 2
## 6: b 6 3
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
## 10: d NA NA
## 1: a 1 4
## 2: a 3 5
## 3: a 6 6
## 4: b 1 1
## 5: b 3 2
## 6: b 6 3
## 7: c 1 7
## 8: c 3 8
## 9: c 6 9
## 10: d NA NA
which TRUE返回匹配的行号,NA返回不匹配的行号,默认FALSE返回匹配的行
DT["d",on="x",which=NA]
##
[1] 1 2 3 4 5 6 7 8 9
.SDcols
取特定的列,然后.SD就包括了页写选定的特定列,可以对这些子集应用函数处理
DT[,lapply(.SD,sum),.SDcols=c("y","v")]
##
y v
## 1: 30 45
## 1: 30 45
评论
发表评论