本文概述
R语言通常被认为是统计学家和数据科学家的语言。很久以前, 这基本上是正确的。但是, 多年来, R通过包提供的灵活性使R成为一种更加通用的语言。 R是1995年开源的, 从那时起R软件包的存储库一直在增长。尽管如此, 与Python之类的语言相比, R还是强烈基于数据。
谈到数据, 表格数据是最常用的数据类型之一, 因此值得特别注意。它是一种数据类型, 对应于数据库中已知的表结构, 其中每一列可以具有不同的类型, 并且该特定数据类型的处理性能是许多应用程序的关键因素。
R可用于表格数据的非常有效的数据处理
鸣叫
在本文中, 我们将介绍如何以有效的方式实现表格数据转换。许多已经使用R进行机器学习的人并不知道在R中可以更快地进行数据处理, 因此他们不需要使用其他工具。
R中的高性能解决方案
Base R在1997年引入了data.frame类, 该类基于之前的S-PLUS。与常用的按行存储数据的数据库不同, R data.frame将数据作为面向列的结构存储在内存中, 因此对于分析中常见的列操作, 它的缓存效率更高。另外, 即使R是一种功能编程语言, 它也不会在开发人员上强制执行。这两个机会已经通过data.table R包得到了很好的解决, 该包可在CRAN存储库中找到。在分组操作时, 它执行得非常快, 并且通过小心实现中间数据子集(例如仅实现特定任务所需的那些列)而特别有效地提高了内存效率。它还在添加或更新列时通过其参考语义避免了不必要的复制。该软件包的第一个版本已于2006年4月发布, 当时显着提高了data.frame的性能。最初的软件包描述是:
该软件包几乎没有。其存在的唯一原因是白皮书指定data.frame必须具有行名。这个包定义了一个新的类data.table, 它的工作方式与data.frame一样, 但是使用的内存减少了10倍, 并且创建(和复制)的速度提高了10倍。它还借此机会允许[]中的subset()和with()之类的表达式。大多数代码是从基本函数复制而来的, 其中删除了操作row.names的代码。
从那时起, data.frame和data.table的实现都得到了改进, 但是data.table仍然比base R快得令人难以置信。事实上, data.table不仅比base R快, 而且似乎比base R快。是目前最快的开源数据整理工具, 可与Python Pandas等工具, 列存储数据库或Spark等大数据应用程序竞争。其在分布式共享基础架构上的性能尚未经过基准测试, 但一次最多可以拥有20亿行的行列, 前景可观。出色的性能与功能齐头并进。另外, 随着最近努力使耗时的零件并行化以提高性能, 似乎很明确地朝着提高性能极限的方向发展。
数据转换示例
由于R可以交互工作, 因此学习R变得容易一些, 因此我们可以逐步遵循示例, 并随时查看每个步骤的结果。在开始之前, 让我们从CRAN信息库安装data.table软件包。
install.packages("data.table")
有用的提示:我们只要打开带有任何问号的名称, 即?install.packages, 就可以打开任何功能的手册。
将数据加载到R中
有很多软件包可以从各种格式和数据库中提取数据, 其中通常包括本机驱动程序。我们将从CSV文件加载数据, 这是原始表格数据的最常见格式。在以下示例中使用的文件可以在这里找到。我们无需担心CSV的读取性能, 因为fread功能在此基础上进行了高度优化。
为了使用包中的任何函数, 我们需要通过库调用来加载它。
library(data.table)
DT <- fread("flights14.csv")
print(DT)
## year month day dep_delay arr_delay carrier origin dest air_time
## 1: 2014 1 1 14 13 AA JFK LAX 359
## 2: 2014 1 1 -3 13 AA JFK LAX 363
## 3: 2014 1 1 2 9 AA JFK LAX 351
## 4: 2014 1 1 -8 -26 AA LGA PBI 157
## 5: 2014 1 1 2 1 AA JFK LAX 350
## ---
## 253312: 2014 10 31 1 -30 UA LGA IAH 201
## 253313: 2014 10 31 -5 -14 UA EWR IAH 189
## 253314: 2014 10 31 -8 16 MQ LGA RDU 83
## 253315: 2014 10 31 -4 15 MQ LGA DTW 75
## 253316: 2014 10 31 -5 1 MQ LGA SDF 110
## distance hour
## 1: 2475 9
## 2: 2475 11
## 3: 2475 19
## 4: 1035 7
## 5: 2475 13
## ---
## 253312: 1416 14
## 253313: 1400 8
## 253314: 431 11
## 253315: 502 11
## 253316: 659 8
如果我们的数据没有很好地建模以进行进一步处理, 因为它们需要从长到宽或从宽到长(也称为透视和非透视)格式进行重塑, 我们可以看一下dcast和melt函数, 从reshape2包中知道。但是, data.table为data.table / data.frame类实现了更快且内存效率更高的方法。
用data.table语法查询
如果你熟悉data.frame
查询data.table与查询data.frame非常相似。在对i参数进行过滤时, 我们可以直接使用列名, 而无需使用$符号访问它们, 例如df [df $ col> 1, ]。当提供下一个参数j时, 我们提供了一个要在data.table范围内求值的表达式。要传递非表达式j参数, 请使用= FALSE。 data.frame方法中不存在的第三个参数定义了组, 从而使j中的表达式可以被组评估。
# data.frame
DF[DF$col1 > 1L, c("col2", "col3")]
# data.table
DT[col1 > 1L, .(col2, col3), ...] # by group using: `by = col4`
如果你熟悉数据库
查询data.table在许多方面都与更多人可能熟悉的SQL查询相对应。下面的DT表示data.table对象, 并且对应于SQLs FROM子句。
DT[ i = where, j = select | update, by = group by]
[ having, ... ]
[ order by, ... ]
[ ... ] ... [ ... ]
排序行和重新排序列
数据排序是时间序列的重要转换, 也是导入数据提取和表示的基础。可以通过向i参数提供行顺序的整数矢量来实现排序, 方法与data.frame相同。查询顺序中的第一个参数(carrier, -dep_delay)将在carrier字段中以升序选择数据, 而在dep_delay度量中以降序选择数据。如上一节所述, 第二个参数j定义要返回的列(或表达式)及其顺序。
ans <- DT[order(carrier, -dep_delay), .(carrier, origin, dest, dep_delay)]
head(ans)
## carrier origin dest dep_delay
## 1: AA EWR DFW 1498
## 2: AA JFK BOS 1241
## 3: AA EWR DFW 1071
## 4: AA EWR DFW 1056
## 5: AA EWR DFW 1022
## 6: AA EWR DFW 989
为了通过引用对数据重新排序, 而不是按特定的顺序查询数据, 我们使用set *函数。
setorder(DT, carrier, -dep_delay)
leading.cols <- c("carrier", "dep_delay")
setcolorder(DT, c(leading.cols, setdiff(names(DT), leading.cols)))
print(DT)
## carrier dep_delay year month day arr_delay origin dest air_time
## 1: AA 1498 2014 10 4 1494 EWR DFW 200
## 2: AA 1241 2014 4 15 1223 JFK BOS 39
## 3: AA 1071 2014 6 13 1064 EWR DFW 175
## 4: AA 1056 2014 9 12 1115 EWR DFW 198
## 5: AA 1022 2014 6 16 1073 EWR DFW 178
## ---
## 253312: WN -12 2014 3 9 -21 LGA BNA 115
## 253313: WN -13 2014 3 10 -18 EWR MDW 112
## 253314: WN -13 2014 5 17 -30 LGA HOU 202
## 253315: WN -13 2014 6 15 10 LGA MKE 101
## 253316: WN -13 2014 8 19 -30 LGA CAK 63
## distance hour
## 1: 1372 7
## 2: 187 13
## 3: 1372 10
## 4: 1372 6
## 5: 1372 7
## ---
## 253312: 764 16
## 253313: 711 20
## 253314: 1428 17
## 253315: 738 20
## 253316: 397 16
通常, 我们既不需要原始数据集, 也不需要排序/排序的数据集。默认情况下, 与其他函数式编程语言类似, R语言将返回已排序的数据作为新对象, 因此将需要比按引用排序的内存多一倍的内存。
子集查询
让我们为航班起点” JFK”和从6到9的月份创建一个子集数据集。在第二个参数中, 我们将结果子集到列出的列中, 并添加一个计算出的变量sum_delay。
ans <- DT[origin == "JFK" & month %in% 6:9, .(origin, month, arr_delay, dep_delay, sum_delay = arr_delay + dep_delay)]
head(ans)
## origin month arr_delay dep_delay sum_delay
## 1: JFK 7 925 926 1851
## 2: JFK 8 727 772 1499
## 3: JFK 6 466 451 917
## 4: JFK 7 414 450 864
## 5: JFK 6 411 442 853
## 6: JFK 6 333 343 676
默认情况下, 在单列data.table上设置数据集时, 将自动为该列创建索引。这将对该列上的所有进一步过滤调用产生实时答案。
更新数据集
使用:=运算符通过引用添加新列, 它会将变量分配到适当的数据集中。这样可以避免在内存中复制数据集, 因此我们无需将结果分配给每个新变量。
DT[, sum_delay := arr_delay + dep_delay]
head(DT)
## carrier dep_delay year month day arr_delay origin dest air_time
## 1: AA 1498 2014 10 4 1494 EWR DFW 200
## 2: AA 1241 2014 4 15 1223 JFK BOS 39
## 3: AA 1071 2014 6 13 1064 EWR DFW 175
## 4: AA 1056 2014 9 12 1115 EWR DFW 198
## 5: AA 1022 2014 6 16 1073 EWR DFW 178
## 6: AA 989 2014 6 11 991 EWR DFW 194
## distance hour sum_delay
## 1: 1372 7 2992
## 2: 187 13 2464
## 3: 1372 10 2135
## 4: 1372 6 2171
## 5: 1372 7 2095
## 6: 1372 11 1980
要一次添加更多变量, 可以从数据集中查询时使用DT [, :=(sum_delay = arr_delay + dep_delay)]语法, 类似于。(sum_delay = arr_delay + dep_delay)。
仅通过与i参数组合, 就可以通过引用进行子分配, 仅更新特定的行。
DT[origin=="JFK", distance := NA]
head(DT)
## carrier dep_delay year month day arr_delay origin dest air_time
## 1: AA 1498 2014 10 4 1494 EWR DFW 200
## 2: AA 1241 2014 4 15 1223 JFK BOS 39
## 3: AA 1071 2014 6 13 1064 EWR DFW 175
## 4: AA 1056 2014 9 12 1115 EWR DFW 198
## 5: AA 1022 2014 6 16 1073 EWR DFW 178
## 6: AA 989 2014 6 11 991 EWR DFW 194
## distance hour sum_delay
## 1: 1372 7 2992
## 2: NA 13 2464
## 3: 1372 10 2135
## 4: 1372 6 2171
## 5: 1372 7 2095
## 6: 1372 11 1980
汇总数据
为了汇总数据, 我们在方括号中提供第三个参数。然后, 在j中, 我们需要提供聚合函数调用, 以便可以实际聚合数据。 j参数中使用的.N符号对应于每个组中所有观测值的数量。如前所述, 聚合可以与行和选择列上的子集结合。
ans <- DT[, .(m_arr_delay = mean(arr_delay), m_dep_delay = mean(dep_delay), count = .N), .(carrier, month)]
head(ans)
## carrier month m_arr_delay m_dep_delay count
## 1: AA 10 5.541959 7.591497 2705
## 2: AA 4 1.903324 3.987008 2617
## 3: AA 6 8.690067 11.476475 2678
## 4: AA 9 -1.235160 3.307078 2628
## 5: AA 8 4.027474 8.914054 2839
## 6: AA 7 9.159886 11.665953 2802
通常, 我们可能需要将行的值与其在组中的汇总进行比较。在SQL中, 我们通过以下方法将聚合应用于分区:AVG(arr_delay)OVER(按载体分类, 月份)。
ans <- DT[, .(arr_delay, carrierm_mean_arr = mean(arr_delay), dep_delay, carrierm_mean_dep = mean(dep_delay)), .(carrier, month)]
head(ans)
## carrier month arr_delay carrierm_mean_arr dep_delay carrierm_mean_dep
## 1: AA 10 1494 5.541959 1498 7.591497
## 2: AA 10 840 5.541959 848 7.591497
## 3: AA 10 317 5.541959 338 7.591497
## 4: AA 10 292 5.541959 331 7.591497
## 5: AA 10 322 5.541959 304 7.591497
## 6: AA 10 306 5.541959 299 7.591497
如果我们不想使用这些汇总查询数据, 而是通过引用将其放入实际的表更新中, 则可以使用:=运算符来实现。这样可以避免数据集在内存中的复制, 因此我们无需将结果分配给新变量。
DT[, `:=`(carrierm_mean_arr = mean(arr_delay), carrierm_mean_dep = mean(dep_delay)), .(carrier, month)]
head(DT)
## carrier dep_delay year month day arr_delay origin dest air_time
## 1: AA 1498 2014 10 4 1494 EWR DFW 200
## 2: AA 1241 2014 4 15 1223 JFK BOS 39
## 3: AA 1071 2014 6 13 1064 EWR DFW 175
## 4: AA 1056 2014 9 12 1115 EWR DFW 198
## 5: AA 1022 2014 6 16 1073 EWR DFW 178
## 6: AA 989 2014 6 11 991 EWR DFW 194
## distance hour sum_delay carrierm_mean_arr carrierm_mean_dep
## 1: 1372 7 2992 5.541959 7.591497
## 2: NA 13 2464 1.903324 3.987008
## 3: 1372 10 2135 8.690067 11.476475
## 4: 1372 6 2171 -1.235160 3.307078
## 5: 1372 7 2095 8.690067 11.476475
## 6: 1372 11 1980 8.690067 11.476475
联接数据集
数据集的基本R加入和合并被认为是子集操作的一种特殊类型。我们提供一个想要加入第一个方括号参数i的数据集。对于提供给i的数据集中的每一行, 我们匹配使用[的数据集中的行。如果我们只想保留匹配的行(内部联接), 那么我们传递一个额外的参数nomatch = 0L。我们使用on参数来指定要在其上连接两个数据集的列。
# create reference subset
carrierdest <- DT[, .(count=.N), .(carrier, dest) # count by carrier and dest
][1:10 # just 10 first groups
] # chaining `[...][...]` as subqueries
print(carrierdest)
## carrier dest count
## 1: AA DFW 5877
## 2: AA BOS 1173
## 3: AA ORD 4798
## 4: AA SEA 298
## 5: AA EGE 85
## 6: AA LAX 3449
## 7: AA MIA 6058
## 8: AA SFO 1312
## 9: AA AUS 297
## 10: AA DCA 172
# outer join
ans <- carrierdest[DT, on = c("carrier", "dest")]
print(ans)
## carrier dest count dep_delay year month day arr_delay origin
## 1: AA DFW 5877 1498 2014 10 4 1494 EWR
## 2: AA BOS 1173 1241 2014 4 15 1223 JFK
## 3: AA DFW 5877 1071 2014 6 13 1064 EWR
## 4: AA DFW 5877 1056 2014 9 12 1115 EWR
## 5: AA DFW 5877 1022 2014 6 16 1073 EWR
## ---
## 253312: WN BNA NA -12 2014 3 9 -21 LGA
## 253313: WN MDW NA -13 2014 3 10 -18 EWR
## 253314: WN HOU NA -13 2014 5 17 -30 LGA
## 253315: WN MKE NA -13 2014 6 15 10 LGA
## 253316: WN CAK NA -13 2014 8 19 -30 LGA
## air_time distance hour sum_delay carrierm_mean_arr
## 1: 200 1372 7 2992 5.541959
## 2: 39 NA 13 2464 1.903324
## 3: 175 1372 10 2135 8.690067
## 4: 198 1372 6 2171 -1.235160
## 5: 178 1372 7 2095 8.690067
## ---
## 253312: 115 764 16 -33 6.921642
## 253313: 112 711 20 -31 6.921642
## 253314: 202 1428 17 -43 22.875845
## 253315: 101 738 20 -3 14.888889
## 253316: 63 397 16 -43 7.219670
## carrierm_mean_dep
## 1: 7.591497
## 2: 3.987008
## 3: 11.476475
## 4: 3.307078
## 5: 11.476475
## ---
## 253312: 11.295709
## 253313: 11.295709
## 253314: 30.546453
## 253315: 24.217560
## 253316: 17.038047
# inner join
ans <- DT[carrierdest, # for each row in carrierdest
nomatch = 0L, # return only matching rows from both tables
on = c("carrier", "dest")] # joining on columns carrier and dest
print(ans)
## carrier dep_delay year month day arr_delay origin dest air_time
## 1: AA 1498 2014 10 4 1494 EWR DFW 200
## 2: AA 1071 2014 6 13 1064 EWR DFW 175
## 3: AA 1056 2014 9 12 1115 EWR DFW 198
## 4: AA 1022 2014 6 16 1073 EWR DFW 178
## 5: AA 989 2014 6 11 991 EWR DFW 194
## ---
## 23515: AA -8 2014 10 11 -13 JFK DCA 53
## 23516: AA -9 2014 5 21 -12 JFK DCA 52
## 23517: AA -9 2014 6 5 -6 JFK DCA 53
## 23518: AA -9 2014 10 2 -21 JFK DCA 51
## 23519: AA -11 2014 5 27 10 JFK DCA 55
## distance hour sum_delay carrierm_mean_arr carrierm_mean_dep count
## 1: 1372 7 2992 5.541959 7.591497 5877
## 2: 1372 10 2135 8.690067 11.476475 5877
## 3: 1372 6 2171 -1.235160 3.307078 5877
## 4: 1372 7 2095 8.690067 11.476475 5877
## 5: 1372 11 1980 8.690067 11.476475 5877
## ---
## 23515: NA 15 -21 5.541959 7.591497 172
## 23516: NA 15 -21 4.150172 8.733665 172
## 23517: NA 15 -15 8.690067 11.476475 172
## 23518: NA 15 -30 5.541959 7.591497 172
## 23519: NA 15 -1 4.150172 8.733665 172
请注意, 由于与基本R子集的一致性, 默认情况下, 外部联接为RIGHT OUTER。如果要寻找LEFT OUTER, 则需要交换表, 如上例所示。确切的行为也可以在merge data.table方法中轻松控制, 使用与R基合并data.frame相同的API。
如果我们只想在数据集中查找列, 则可以在加入时使用j参数中的:=运算符有效地做到这一点。正如我们在”更新数据集”部分中所述, 通过引用进行子分配的方式相同, 我们现在刚刚从要加入的数据集中通过引用添加一列。这样可以避免在内存中复制数据, 因此我们不需要将结果分配给新变量。
DT[carrierdest, # data.table to join with
lkp.count := count, # lookup `count` column from `carrierdest`
on = c("carrier", "dest")] # join by columns
head(DT)
## carrier dep_delay year month day arr_delay origin dest air_time
## 1: AA 1498 2014 10 4 1494 EWR DFW 200
## 2: AA 1241 2014 4 15 1223 JFK BOS 39
## 3: AA 1071 2014 6 13 1064 EWR DFW 175
## 4: AA 1056 2014 9 12 1115 EWR DFW 198
## 5: AA 1022 2014 6 16 1073 EWR DFW 178
## 6: AA 989 2014 6 11 991 EWR DFW 194
## distance hour sum_delay carrierm_mean_arr carrierm_mean_dep lkp.count
## 1: 1372 7 2992 5.541959 7.591497 5877
## 2: NA 13 2464 1.903324 3.987008 1173
## 3: 1372 10 2135 8.690067 11.476475 5877
## 4: 1372 6 2171 -1.235160 3.307078 5877
## 5: 1372 7 2095 8.690067 11.476475 5877
## 6: 1372 11 1980 8.690067 11.476475 5877
对于加入时的汇总, 请使用= .EACHI。它执行的联接不会实现中间联接结果, 并且会动态应用聚合, 从而提高存储效率。
滚动连接是一项罕见功能, 旨在处理有序数据。它非常适合处理时间数据以及一般的时间序列。它基本上将匹配条件下的匹配滚动到下一个匹配值。加入时通过提供roll参数来使用它。
快速重叠联接通过使用各种重叠运算符(包括在, 在, 开始, 结束中的任何一个), 根据周期及其重叠处理来连接数据集。
当前正在开发使用非等式条件连接数据集的非等式连接功能。
分析数据
在浏览数据集时, 有时我们可能希望收集有关该主题的技术信息, 以更好地理解数据的质量。
描述性统计
summary(DT)
## carrier dep_delay year month
## Length:253316 Min. :-112.00 Min. :2014 Min. : 1.000
## Class :character 1st Qu.: -5.00 1st Qu.:2014 1st Qu.: 3.000
## Mode :character Median : -1.00 Median :2014 Median : 6.000
## Mean : 12.47 Mean :2014 Mean : 5.639
## 3rd Qu.: 11.00 3rd Qu.:2014 3rd Qu.: 8.000
## Max. :1498.00 Max. :2014 Max. :10.000
##
## day arr_delay origin dest
## Min. : 1.00 Min. :-112.000 Length:253316 Length:253316
## 1st Qu.: 8.00 1st Qu.: -15.000 Class :character Class :character
## Median :16.00 Median : -4.000 Mode :character Mode :character
## Mean :15.89 Mean : 8.147
## 3rd Qu.:23.00 3rd Qu.: 15.000
## Max. :31.00 Max. :1494.000
##
## air_time distance hour sum_delay
## Min. : 20.0 Min. : 80.0 Min. : 0.00 Min. :-224.00
## 1st Qu.: 86.0 1st Qu.: 529.0 1st Qu.: 9.00 1st Qu.: -19.00
## Median :134.0 Median : 762.0 Median :13.00 Median : -5.00
## Mean :156.7 Mean : 950.4 Mean :13.06 Mean : 20.61
## 3rd Qu.:199.0 3rd Qu.:1096.0 3rd Qu.:17.00 3rd Qu.: 23.00
## Max. :706.0 Max. :4963.0 Max. :24.00 Max. :2992.00
## NA's :81483
## carrierm_mean_arr carrierm_mean_dep lkp.count
## Min. :-22.403 Min. :-4.500 Min. : 85
## 1st Qu.: 2.676 1st Qu.: 7.815 1st Qu.:3449
## Median : 6.404 Median :11.354 Median :5877
## Mean : 8.147 Mean :12.465 Mean :4654
## 3rd Qu.: 11.554 3rd Qu.:17.564 3rd Qu.:6058
## Max. : 86.182 Max. :52.864 Max. :6058
## NA's :229797
基数
我们可以使用uniqueN函数检查数据的唯一性, 并将其应用于每一列。以下查询中的对象.SD对应于Data.table的子集:
DT[, lapply(.SD, uniqueN)]
## carrier dep_delay year month day arr_delay origin dest air_time
## 1: 14 570 1 10 31 616 3 109 509
## distance hour sum_delay carrierm_mean_arr carrierm_mean_dep lkp.count
## 1: 152 25 1021 134 134 11
NA比率
为了计算每一列的未知值(R中为NA, SQL中为NULL)的比率, 我们提供了所需的函数以应用于每一列。
DT[, lapply(.SD, function(x) sum(is.na(x))/.N)]
## carrier dep_delay year month day arr_delay origin dest air_time
## 1: 0 0 0 0 0 0 0 0 0
## distance hour sum_delay carrierm_mean_arr carrierm_mean_dep lkp.count
## 1: 0.3216654 0 0 0 0 0.9071555
汇出资料
data.table包还提供了将表格数据快速导出为CSV格式的功能。
tmp.csv <- tempfile(fileext=".csv")
fwrite(DT, tmp.csv)
# preview exported data
cat(system(paste("head -3", tmp.csv), intern=TRUE), sep="\n")
## carrier, dep_delay, year, month, day, arr_delay, origin, dest, air_time, distance, hour, sum_delay, carrierm_mean_arr, carrierm_mean_dep, lkp.count
## AA, 1498, 2014, 10, 4, 1494, EWR, DFW, 200, 1372, 7, 2992, 5.54195933456561, 7.59149722735674, 5877
## AA, 1241, 2014, 4, 15, 1223, JFK, BOS, 39, , 13, 2464, 1.90332441727168, 3.98700802445548, 1173
撰写本文时, fwrite函数尚未发布到CRAN存储库。要使用它, 我们需要安装data.table开发版本, 否则我们可以使用base R write.csv函数, 但不要指望它会很快。
资源资源
有大量可用资源。除了每个功能可用的手册之外, 还有软件包小插图, 它们是针对特定主题的教程。这些可以在”入门”页面上找到。此外, “演示文稿”页面列出了来自全球data.table演示文稿的30多种材料(幻灯片, 视频等)。同样, 社区支持也在不断增长, 最近在Stack Overflow data.table标签上达到了第4000个问题, 仍然有很高的回答率(91.9%)。下图显示了随时间推移堆栈溢出的data.table标签问题的数量。
SO每月针对data.table提问-仅标记data.table的问题, 不回答带有data.table的问题(已接受)
总结
本文提供了一些示例, 可以使用data.table包在R中进行有效的表格数据转换。可以通过寻找可重复的基准来检查性能的实际数字。我发表了一篇有关data.table解决方案的总结博客文章, 涉及关于R语言的前50个最受好评的StackOverflow问题, 称为”使用data.table有效解决常见R问题”, 你可以在其中找到大量图形和可复制的代码。包data.table使用本机实现的快速基数排序进行分组操作, 并使用二进制搜索快速子集/联接。此基数排序已从3.3.0版合并到base R中。此外, 该算法最近已在H2O机器学习平台中实现, 并在H2O集群上并行化, 从而可以在10B x 10B行上进行有效的大联接。
相关:使用Supergroup.js进行最终的内存中数据收集操作
评论前必须登录!
注册