readr::read_tsv() 中的 skip = 和 n_max = 参数可用于控制从制表符分隔的文件中读取多少数据到数据框中。
要读取前 10 个观察结果以便查看列名,可以运行:
library(readr)
file_url <- "http://samhda.s3-us-gov-west-1.amazonaws.com/s3fs-public/field-uploads-protected/studies/NSDUH-2002-2018/NSDUH-2002-2018-datasets/NSDUH-2002-2018-DS0001/NSDUH-2002-2018-DS0001-bundles-with-study-info/NSDUH-2002-2018-DS0001-bndl-data-tsv.zip"
zip <- tempfile(fileext = ".zip")
tsv_file <- download.file(file_url, zip, mode = "wb")
unzip_f <- unzip(zip,exdir="./data")
df <- read_tsv(unzip_f, col_names= TRUE, n_max = 10)
此时我们可以使用colnames() 函数检索列名。
col_names <- colnames(df)
我们现在将验证 100,000 行数据消耗的 RAM 量,并计算 100,000 次观察的加载时间。
system.time(df_100000 <- read_tsv("./data/NSDUH_2002_2018_tab.tsv",
col_names = TRUE, n_max = 100000))
format(object.size(df_100000),units = "auto")
user system elapsed
55.276 4.136 60.559
> format(object.size(df_100000),units = "auto")
[1] "2.7 Gb"
此时,我们可以在具有 8Gb RAM 的机器上一次安全地从原始数据文件中读取大约 200,000 个观察值。
接下来,我们将计算出原始数据文件中有多少行数据。我们可以使用read_tsv() 的col_types = 参数并将除第一列之外的所有列设置为-,这告诉read_tsv() 不要读取列。我们还用一列和所有观察值计算数据框的大小。
theTypes <- c("n",rep("_",3661))
system.time(df_obs <- read_tsv("./data/NSDUH_2002_2018_tab.tsv",col_types = theTypes,
col_names = TRUE))
nrow(df_obs)
format(object.size(df_obs),units = "auto")
user system elapsed
175.208 27.694 210.948
> nrow(df_obs)
[1] 949285
> format(object.size(df_obs),units = "auto")
[1] "39.8 Mb"
在配备英特尔 i7-4870HQ 处理器、频率为 2.5Ghz 的 MacBook Pro 15 上,从原始数据文件中读取单列数据的所有观察结果花了将近 4 分钟。
nrow() 的结果告诉我们原始数据文件中有 949,285 行。如果我们将文件分成 200,000 个观察块,我们可以读取它们并将它们保存为带有saveRDS() 的 RDS 文件以供后续处理。
迭代读取文件并写入RDS
for(i in 1:5){
df <- read_tsv("./data/NSDUH_2002_2018_tab.tsv",
skip = (i - 1) * 200000,
n_max = 200000,
col_names = c_names)
saveRDS(df,paste0("./data/usnuh_",i,".RDS"))
}
此时,usnuh_1.RDS 到 usnuh_5.RDS 可以单独读入 R 并进行分析。
注意:for() 循环会覆盖上一次迭代中创建的数据帧,因此我们可以读取和写入所有文件而不会耗尽 RAM。重要的是要记住,一个人只能加载 1 个包含 200,000 个观察值的文件,并将其用于具有 8Gb RAM 的机器上的数据分析。为了使用数据的不同部分,需要使用rm() 函数删除当前数据,然后再将另外 200,000 个观测 RDS 文件加载到 RAM 中。
读取最后 200,000 行
根据 cmets,这是可用于读取文件最后 200K 行的代码。
# read last 200K rows. first read one row to obtain column names
library(readr)
df <- read_tsv("./data/NSDUH_2002_2018_tab.tsv",
col_names = TRUE, n_max = 1)
c_names <- colnames(df)
# next, configure skip = relative to end of file and read
df <- read_tsv("./data/NSDUH_2002_2018_tab.tsv",
skip = (949258 - 200000),
n_max = 200000,
col_names = c_names)
当我们在环境查看器中查看数据框时,我们可以看到它包含 200,000 个观察值。