关于r:R语言之处理大型数据集的策略

43次阅读

共计 3227 个字符,预计需要花费 9 分钟才能阅读完成。

文章和代码曾经归档至【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) <- varnames
names(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)

正文完
 0