文章和代码曾经归档至【Github仓库:https://github.com/timerring/dive-into-AI 】或者公众号【AIShareLab】回复 R语言 也可获取。

在理论的问题中,数据分析者面对的可能是有几十万条记录、几百个变量的数据集。解决这种大型的数据集须要耗费计算机比拟大的内存空间,所以尽可能应用 64 位的操作系统和内存比拟大的设施。否则,数据分析可能要花太长时间甚至无奈进行。此外,解决数据的无效策略能够在很大水平上进步剖析效率。

1. 清理工作空间

为了在数据分析时取得尽可能大的内存空间,倡议在启动任何新的剖析我的项目时,首先清理工作空间。

# rm(list = ls(all = TRUE))

函数 ls( ) 用于显示当前工作空间中的对象,其中参数 all 默认为 FALSE,这里设为 TRUE 是为革除包含暗藏对象在内的所有对象。

此外,在数据分析的过程中,对于长期对象和不再须要的对象,应用命令 rm(object1,object2, …) 及时将它们革除。

2. 疾速读取.csv 文件

.csv 文件占用空间小,能够由 Excel 查看和生成,因而被宽泛使用于存储数据。在后面里介绍的函数 read.csv( ) 能够很不便地读取 .csv 文件。然而,对于大型数据集,该函数读取数据的速度太慢,有时甚至会报错。这时,能够应用 readr 包里的 read_csv( ) 函数或者 data.table 包里的 fread( ) 函数读入数据,其中后者的读取速度更快(大概为前者的两倍)

data.table 包提供了一个数据框的高级版本,大大提高了数据处理的速度。该包尤其适宜那些须要在内存中解决大型数据集(比方 1GB~100GB)的用户。不过,这个包的操作形式与 R 中其余包相差较大,须要投入肯定的工夫学习。

3. 模仿一个大型数据集

为了便于阐明,上面模仿一个大型数据集,该数据集蕴含 50000 条记录、200 个变量。

bigdata <- as.data.frame(matrix(rnorm(50000 * 200), ncol = 200))# 应用了嵌套的两个 for 循环语句和 R 的内置常量 letters(小写英文字母)为 200 个变量命名。varnames <- NULL# 里面一层循环语句构建变量名的第一个字符(a~t)for (i in letters[1:20]) {# 外面一层循环语句把数字 1~10 用 `_` 作为分隔符别离连贯到这些字母上。  for (j in 1:10) {  # 函数 paste( ) 用于连贯字符串。    varnames <- c(varnames, paste(i, j, sep = "_"))  }}names(bigdata) <- varnamesnames(bigdata)

如果你不太想应用多个循环,能够思考:

# 惋惜 apply 此处会导致多余的空格# apply(expand.grid(1:20, letters[1:20]), 1, function(x) paste(x[2], x[1], sep="_")) # sprintf("%s_%s", expand.grid(1:10,letters[1:20])[,2],expand.grid(1:10,letters[1:20])[,1])# 或者# as.vector(t(outer(letters[1:20], 1:10, paste, sep="_")))

4. 剔除不须要的变量

在进行正式的剖析之前,咱们须要把临时用不上的变量剔除以缩小内存的累赘。dplyr 包的 select 系列函数在这里能够派上用场,尤其是将这些函数与 tidyselect 包的 starts_with( )、ends_with( ) 和 contains( ) 等函数联结应用会带来诸多便当。

先加载这两个包:

library(dplyr)library(tidyselect)

接下来举例说明如何应用 select 系列函数抉择或剔除变量。

subdata1 <- select(bigdata, starts_with("a"))names(subdata1)# 'a_1''a_2''a_3''a_4''a_5''a_6''a_7''a_8''a_9''a_10'subdata2 <- select(bigdata, ends_with("2"))names(subdata2)#'a_2''b_2''c_2''d_2''e_2''f_2''g_2''h_2''i_2''j_2''k_2''l_2''m_2''n_2''o_2''p_2''q_2''r_2''s_2''t_2'

函数 starts_with( ) ends_with( ) 别离示意变量的前缀和后缀。在下面的命令中,subdata1 选取了数据集里所有以 a 结尾的变量,而 subdata2 选取了数据集里所有以 2 结尾的变量。

如果要选取所有以 ab 结尾的变量,能够应用上面的命令:

# subdata3 <- select(bigdata, c(starts_with("a"), starts_with("b")))subdata3 <- select_at(bigdata, vars(starts_with("a"), starts_with("b"))) # 留神跟 select 语法稍有不同names(subdata3)

要抉择变量名里蕴含某些字符的所有变量,能够借助函数 contains( ) 实现。例如,要抉择蕴含字符 1 的所有变量,能够输出上面的命令:

# subdata4 <- select(bigdata, c(contains("1")))subdata4 <- select_at(bigdata, vars(contains("1")))names(subdata4)

须要留神的是,所有以 10 结尾的变量也是蕴含字符 1 的。

如果要剔除某些变量,只须要在函数 starts_with( )、ends_with( ) 和 contains( ) 后面加上 - 号。例如,要剔除以 15 结尾的变量,能够应用上面的命令:

# subdata5 <- select(bigdata, c(-contains("1"), -contains("5")))subdata5 <- select_at(bigdata, vars(-contains("1"), -contains("5")))names(subdata5)

5. 选取数据集的一个随机样本

对大型数据集的全副记录进行解决往往会升高剖析的效率。在编写代码时,能够只抽取一部分记录对程序进行测试,以便优化代码并打消 bug。

# 参数 size 用于指定行的个数sampledata1 <- sample_n(subdata5, size = 500)nrow(sampledata1)# 参数 size 用于指定占所有行的比例。sampledata2 <- sample_frac(subdata5, size = 0.02)nrow(sampledata2)# 500# 1000

函数 sample_n( ) 和 sample_frac( ) 都用于从数据框中随机选取指定数量的行,前者中的参数 size 用于指定行的个数,而后者中的参数 size 用于指定占所有行的比例。

须要阐明的是,下面探讨的解决大型数据集的策略只实用于解决 GB 级的数据集。不管用哪种工具,解决 TB 和 PB 级的数据集都是一种挑战。R 中有几个包能够用于解决 TB 级数据集,例如 RHIPE、RHadoop 和 RevoScaleR 等。这些包的学习曲线绝对平缓,须要对高性能计算有肯定的理解,有需要的话你能够自行摸索,这里不做介绍。

sample_n() 和 sample_frac() 行将退休,包文档中举荐改用 slice_sample( ),用法可查看此处。
# 应用 slice_sample( ) 进行解决sampledata1 <- slice_sample(subdata5, n = 500)nrow(sampledata1)sampledata2 <- slice_sample(subdata5, prop = 0.02)nrow(sampledata2)