data.table没有行名称。
b)?一般形式
为了让大家快速理解data.table语法的一般形式,先看看如下说明:
DT[i,0);">j,0);">by] ## ? R: ? i ? ? ?j ? ? ? ? ?by ## SQL: where select|update group by
看看上述描述,如果你了解sql语言,可能你就能很快明白data.table的语法。对于一个数据集DT ,用i 对数据的行数进行筛选,用j 对数据的列进行筛选以及计算,用by 来指定数据如何进行分组。接下来我们就来看看如何利用i 和j 对数据进行处理。
c) 用i 筛选行数
# 筛选出得分大于40并且助攻数大于7次的数据 ans pts > 40 & ast >= 8]headans# ? ?rk player wl ? ? ? ? ? match gs min ? fgp fgm fga ? ?p3p p3m p3a ? ?ftp# 1: 25 ? 库里 胜 魔术114-130勇士 ?1 ?34 74.1% ?20 ?27 ?66.7% ?10 ?15 100.0%# 2: 63 ? 库里 胜 太阳116-135勇士 ?1 ?31 55.0% ?11 ?20 ?56.2% ? 9 ?16 ?90.9%# 3: 77 ? 库里 胜 鹈鹕120-134勇士 ?1 ?36 63.0% ?17 ?27 ?57.1% ? 8 ?14 100.0%# 4: 31 ? 沃尔 负 勇士134-121奇才 ?1 ?35 68.0% ?17 ?25 100.0% ? 3 ? 3 ?66.7%# 5: 23 ? 威少 负 鹈鹕123-119雷霆 ?1 ?38 60.0% ?15 ?25 ?60.0% ? 3 ? 5 ?78.6%# 6: 69 ? 威少 胜 鹈鹕103-110雷霆 ?1 ?36 56.0% ?14 ?25 ? 0.0% ? 0 ? 3 ?75.0%# ? ?ftm fta reb oreb dreb ast stl blk tov pf pts # 1: ? 1 ? 1 ? 7 ? ?0 ? ?7 ? 8 ? 0 ? 1 ? 5 ?1 ?51 # 2: ?10 ?11 ? 6 ? ?1 ? ?5 ? 8 ? 2 ? 0 ? 6 ?2 ?41 # 3: ?11 ?11 ? 4 ? ?0 ? ?4 ? 9 ? 4 ? 0 ? 2 ?3 ?53 # 4: ? 4 ? 6 ? 3 ? ?1 ? ?2 ?10 ? 2 ? 0 ? 3 ?4 ?41 # 5: ?11 ?14 ? 4 ? ?2 ? ?2 ? 9 ? 0 ? 0 ? 2 ?3 ?44 # 6: ?15 ?20 ? 9 ? ?3 ? ?6 ? 8 ? 1 ? 1 ? 4 ?1 ?43
– 提取pgdat 的前两行数据
[2ans # ? ?rk player wl ? ? ? ? ? match gs min ? fgp fgm fga ? p3p p3m p3a ? ?ftp # 1: ?1 ? 库里 胜 灰熊104-125勇士 ?1 ?30 62.5% ?15 ?24 52.6% ?10 ?19 100.0% # 2: ?2 ? 库里 胜 ? 马刺86-92勇士 ?1 ?35 59.1% ?13 ?22 44.4% ? 4 ? 9 100.0% # 1: ? 6 ? 6 ? 4 ? ?1 ? ?3 ? 6 ? 2 ? 0 ? 2 ?2 ?46 # 2: ? 7 ? 7 ? 5 ? ?0 ? ?5 ? 5 ? 2 ? 0 ? 4 ?4 ?37
– 排序
我们可以直接用R里自带的函数order 来完成排序。
# 把数据首先按得分降序排列,然后再按助攻数升序排列 order(-pts,0);">ast)# ? ?rk player wl ? ? ? ? ? ? match gs min ? fgp fgm fga ? p3p p3m p3a# 1: 77 ? 库里 胜 ? 鹈鹕120-134勇士 ?1 ?36 63.0% ?17 ?27 57.1% ? 8 ?14 # 2: 33 ? 库里 胜 ? 奇才121-134勇士 ?1 ?36 67.9% ?19 ?28 73.3% ?11 ?15 # 3: 25 ? 库里 胜 ? 魔术114-130勇士 ?1 ?34 74.1% ?20 ?27 66.7% ?10 ?15 # 4: 79 ? 威少 胜 ? 魔术136-139雷霆 ?1 ?48 47.2% ?17 ?36 20.0% ? 1 ? 5 # 5: 70 ? 库里 胜 森林狼116-129勇士 ?1 ?38 60.0% ?15 ?25 61.5% ? 8 ?13 # 6: ?1 ? 库里 胜 ? 灰熊104-125勇士 ?1 ?30 62.5% ?15 ?24 52.6% ?10 ?19 # ? ? ? ftp ftm fta reb oreb dreb ast stl blk tov pf pts # 1: 100.0% ?11 ?11 ? 4 ? ?0 ? ?4 ? 9 ? 4 ? 0 ? 2 ?3 ?53 # 2: ?66.7% ? 2 ? 3 ? 7 ? ?1 ? ?6 ? 2 ? 3 ? 0 ? 7 ?3 ?51 # 3: 100.0% ? 1 ? 1 ? 7 ? ?0 ? ?7 ? 8 ? 0 ? 1 ? 5 ?1 ?51 # 4: ?81.3% ?13 ?16 ?11 ? ?5 ? ?6 ? 8 ? 1 ? 1 ? 6 ?3 ?48 # 5: 100.0% ? 8 ? 8 ? 5 ? ?0 ? ?5 ? 4 ? 2 ? 0 ? 3 ?3 ?46 # 6: 100.0% ? 6 ? 6 ? 4 ? ?1 ? ?3 ? 6 ? 2 ? 0 ? 2 ?2 ?46
在使用order 进行排序时,默认是升序排列,如果需要降序排列,可以在列名前加上- 。 值得一提的是,在data.table里面用到的order实际上经过内部优化过了,它比R自带的order 实际上要快不少,看如下例子:
# Win7 32 # R 3.2.1 odt col=sample(1e7## uses order from base R t1 system.timeans1 odtbase::col]) ? # ? ?user ?system elapsed # ? 10.07 ? ?0.04 ? 10.15 ## uses data.table's forder t2 ans2 ) ? ? ? ? # ? ?0.63 ? ?0.06 ? ?0.69 identicalans1,0);">ans2# [1] TRUE
上述测试在win7的32位系统下进行,内存大小为4GB,R采用的3.2.1版本,我们可以看到加速了~15倍。
d) 用j 选择列
– 选择pts 列,返回向量
[,0);">pts] # [1] 46 37 17 27 21 39
– 选择data.table
list# ? ?pts # 1: ?46 # 2: ?37 # 3: ?17 # 4: ?27 # 5: ?21 # 6: ?39
– 选择pts 和ast 两列数据
– 选择ast 两列数据并且将它们重命名为points 和assists
points assists # ? ?points assists # 1: ? ? 46 ? ? ? 6 # 2: ? ? 37 ? ? ? 5 # 3: ? ? 17 ? ? ? 8 # 4: ? ? 27 ? ? ? 9 # 5: ? ? 21 ? ? ?15 # 6: ? ? 39 ? ? ? 7
e) 用j 来计算
– 计算直接得分和间接得分之和
# 间接得分简单记为助攻数*2 player,0);">tpts + 2*# ? ? ?player tpts # ? 1: ? 库里 ? 58 # ? 2: ? 库里 ? 47 # ? 3: ? 库里 ? 33 # ? 4: ? 库里 ? 45 # ? 5: ? 库里 ? 51 # ?--- ? ? ? ? ? ? # 415: ? 欧文 ? 23 # 416: ? 欧文 ? 26 # 417: ? 欧文 ? 17 # 418: ? 欧文 ? 13 # 419: ? 欧文 ? 20
f) 用i 筛选数据并且用j 做一些计算
– 计算库里的场均得分和助攻数
player == "库里",? ? ? ? ? ? ? .m_ptsmeanm_ast# ? ? ? m_pts ? ?m_ast # 1: 30.06329 6.670886
– 计算得分大于等于20分并且助攻数大于等于10个的两双的总场次
20 10,0);">length# [1] 87
length 用来计算数据的长度,这里的列名实际上选取任意一列都可以,data.table提供了一个相同功能的函数.N 来实现,用来表示数据的行数。于是上述代码可以有以下等价表述方式:
.N# [1] 87
g) 用j 通过字符串的变量名来选择数据列
使用参数with = FALSE
– 跟data.frame相同的方式选择"pts",68);">"ast"with=FALSE# 6: ?39 ? 7
2. 数据整合
介绍完了i 和j 的用法,接下来介绍如何用by 来实现分组数据计算。
a) 用by 分组
– 计算不同球员的参赛场次
by=.player# ? ?player ?N # 1: ? 库里 79 # 2: ? 康利 56 # 3: ? 保罗 74 # 4: ? 沃尔 77 # 5: ? 威少 80 # 6: ? 欧文 53 ## 采用字符串形式 # ans <- pgdat[,.(.N),by="player"]
– 计算不同球员助攻大于等于8次的参赛场次
8,0);">.N,136); font-style: italic;"># 1: ? 库里 30 # 2: ? 康利 17 # 3: ? 保罗 54 # 4: ? 沃尔 62 # 5: ? 威少 61 # 6: ? 欧文 ?8
– 计算不同球员在不同胜负关系下助攻大于等于8次的参赛场次
wl# ? ? player wl ?N # ?1: ? 库里 胜 28 # ?2: ? 库里 负 ?2 # ?3: ? 康利 胜 14 # ?4: ? 康利 负 ?3 # ?5: ? 保罗 胜 34 # ?6: ? 保罗 负 20 # ?7: ? 沃尔 负 29 # ?8: ? 沃尔 胜 33 # ?9: ? 威少 胜 44 # 10: ? 威少 负 17 # 11: ? 欧文 负 ?2 # 12: ? 欧文 胜 ?6
– 计算不同球员在不同胜负关系下场均得分与助攻数
## j设置参数名 # ? ? player wl ? ? ? V1 ? ? ? ?V2 # ?1: ? 库里 胜 30.39437 ?6.647887 # ?2: ? 库里 负 27.12500 ?6.875000 # ?3: ? 康利 负 13.95652 ?5.000000 # ?4: ? 康利 胜 16.24242 ?6.878788 # ?5: ? 保罗 胜 18.98000 10.240000 # ?6: ? 保罗 负 20.70833 ?9.416667 # ?7: ? 沃尔 负 18.80000 ?9.400000 # ?8: ? 沃尔 胜 21.05405 11.162162 # ?9: ? 威少 胜 22.30909 10.563636 # 10: ? 威少 负 26.04000 10.120000 # 11: ? 欧文 胜 20.08108 ?4.783784 # 12: ? 欧文 负 18.62500 ?4.562500 ## j不设置参数名 mpts mast ? ? ? ? ? ? ?# ? ? player wl ? ? mpts ? ? ?mast # 12: ? 欧文 负 18.62500 ?4.562500
|