sah*_*uno 1 r fread data.table
读取大文件 ~335GB 时 fread() 失败并出现此错误。感谢任何有关如何解决此问题的建议。
opt$input_file <- "sample-009_T/per_read_modified_base_calls.txt"
Error in data.table::fread(opt$input_file, nThread = 16) :
long vectors not supported yet: ../../src/include/Rinlinedfuns.h:537
Execution halted
Run Code Online (Sandbox Code Playgroud)
文件大小和片段
(base) bash-4.2$ ls -thl per_read_modified_base_calls.txt
-rw-r--r-- 1 lih7 user 335G May 31 15:24 per_read_modified_base_calls.txt
(base) bash-4.2$ head per_read_modified_base_calls.txt
read_id chrm strand pos mod_log_prob can_log_prob mod_base
d1c2a9e7-8655-4393-8ab1-c1fa47b0dc5c chr12 + 94372964 -8.814943313598633 -8.695793370588385 h
d1c2a9e7-8655-4393-8ab1-c1fa47b0dc5c chr12 + 94372964 -0.00031583529198542237 -8.695793370588385 m
2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929450 -3.0660934448242188 -5.948376270726361 h
2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929450 -0.05046514421701431 -5.948376270726361 m
2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929897 -8.683683395385742 -9.392607152489518 h
2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929897 -0.00025269604520872235 -9.392607152489518 m
2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929959 -8.341853141784668 -8.957908916643804 h
2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929959 -0.0003671127778943628 -8.957908916643804 m
2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929670 -3.8058860301971436 -9.161674497706297 h
Run Code Online (Sandbox Code Playgroud)
您的系统上似乎不太可能有足够的 RAM 来加载大小为 335GB 的文件。我建议您找到一种“懒惰”的方式来读取数据。
\n前面:我假设该文件确实是制表符分隔的。如果没有,那么我不知道任何懒惰的方法都会有效......
\n由于您已经标记了data.table,除非您尝试data.table仅使用其所谓的内存效率(当然可能......并且它是高效的),否则我会假设您想继续使用data.table-语法,下面列出的 arrow/duckdb 均不立即支持。然而,一旦你获得了collect()数据,你就可以轻松地as.data.table()使用它,此时你可以返回使用data.table-syntax。
使用该包的(众多)好处之一arrow是它与dplyr.
arr <- arrow::read_delim_arrow("calls.txt", delim = "\\t", as_data_frame = FALSE)\narr\n# Table\n# 9 rows x 7 columns\n# $read_id <string>\n# $chrm <string>\n# $strand <string>\n# $pos <int64>\n# $mod_log_prob <double>\n# $can_log_prob <double>\n# $mod_base <string>\nRun Code Online (Sandbox Code Playgroud)\n这本身并不令人印象深刻,但我们可以构建一个完整的(有限的)dplyr 表达式序列,然后在准备好时调用,collect()此时数据最终从磁盘拉入内存。
library(dplyr)\narr %>%\n filter(grepl("d1c2", read_id)) %>%\n collect()\n# # A tibble: 2 \xc3\x97 7\n# read_id chrm strand pos mod_log_prob can_log_prob mod_base\n# <chr> <chr> <chr> <int> <dbl> <dbl> <chr> \n# 1 d1c2a9e7-8655-4393-8ab1-c1fa47b0dc5c chr12 + 94372964 -8.81 -8.70 h \n# 2 d1c2a9e7-8655-4393-8ab1-c1fa47b0dc5c chr12 + 94372964 -0.000316 -8.70 m \n\narr %>%\n count(chrm) %>%\n collect()\n# # A tibble: 2 \xc3\x97 2\n# chrm n\n# <chr> <int>\n# 1 chr12 2\n# 2 chr10 7\n\narr %>%\n group_by(chrm) %>%\n summarize(across(c(mod_log_prob, can_log_prob), ~ max(.))) %>%\n collect()\n# # A tibble: 2 \xc3\x97 3\n# chrm mod_log_prob can_log_prob\n# <chr> <dbl> <dbl>\n# 1 chr12 -0.000316 -8.70\n# 2 chr10 -0.000253 -5.95\nRun Code Online (Sandbox Code Playgroud)\n在每个示例中,磁盘上的数据直到 才会读入内存collect(),因此读入 R 的数据可以足够小。(请注意,导致太大对象的摘要仍然会失败,这不会神奇地为您提供更多明显的 RAM。)
dplyr(可以在此处找到受支持操作的完整或接近完整列表:https: //arrow.apache.org/docs/dev/r/reference/acero.html)。
(这也可以使用 轻松完成RSQLite,它们都有相似的功能。)
library(duckdb)\ndb <- dbConnect(duckdb::duckdb(), dbdir = "calls.db")\nduckdb_read_csv(db, name = "calls", files = "calls.txt", delim = "\\t")\ndbListFields(db, "calls")\n# [1] "read_id" "chrm" "strand" "pos" "mod_log_prob" "can_log_prob" "mod_base" \ndbGetQuery(db, "select read_id, chrm, mod_log_prob from calls where read_id like \'d1c2%\'")\n# read_id chrm mod_log_prob\n# 1 d1c2a9e7-8655-4393-8ab1-c1fa47b0dc5c chr12 -8.8149433136\n# 2 d1c2a9e7-8655-4393-8ab1-c1fa47b0dc5c chr12 -0.0003158353\nRun Code Online (Sandbox Code Playgroud)\n如果您已经熟悉 SQL,那么这种方法可能会很好。
\n请注意,您仍然可以使用dplyr此方法:
library(dplyr)\ncalls_table <- tbl(db, "calls")\ncalls_table\n# # Source: table<calls> [9 x 7]\n# # Database: DuckDB 0.7.1 [r2@Linux 6.2.0-20-generic:R 4.2.3/calls.db]\n# read_id chrm strand pos mod_log_prob can_log_prob mod_base\n# <chr> <chr> <chr> <int> <dbl> <dbl> <chr> \n# 1 d1c2a9e7-8655-4393-8ab1-c1fa47b0dc5c chr12 + 94372964 -8.81 -8.70 h \n# 2 d1c2a9e7-8655-4393-8ab1-c1fa47b0dc5c chr12 + 94372964 -0.000316 -8.70 m \n# 3 2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929450 -3.07 -5.95 h \n# 4 2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929450 -0.0505 -5.95 m \n# 5 2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929897 -8.68 -9.39 h \n# 6 2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929897 -0.000253 -9.39 m \n# 7 2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929959 -8.34 -8.96 h \n# 8 2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929959 -0.000367 -8.96 m \n# 9 2109b127-c835-47f3-b215-c238438829b6 chr10 - 118929670 -3.81 -9.16 h \nRun Code Online (Sandbox Code Playgroud)\n请注意,这里看起来好像已经将所有数据读入内存,但它只是给您提供了数据样本;当你有很多行时,它只会加载一些来显示它可能是什么,但最终仍然需要你collect()。模仿上面:
\ncalls_table %>%\n filter(grepl("d1c2", read_id)) %>%\n collect()\n# # A tibble: 2 \xc3\x97 7\n# read_id chrm strand pos mod_log_prob can_log_prob mod_base\n# <chr> <chr> <chr> <int> <dbl> <dbl> <chr> \n# 1 d1c2a9e7-8655-4393-8ab1-c1fa47b0dc5c chr12 + 94372964 -8.81 -8.70 h \n# 2 d1c2a9e7-8655-4393-8ab1-c1fa47b0dc5c chr12 + 94372964 -0.000316 -8.70 m \nRun Code Online (Sandbox Code Playgroud)\n还有其他几个包在这里也可能有用。我没有和他们打交道的经验。
\nfstdisk.frame(当其他人提出建议时,我将添加到此列表中。我既不认可也不羞辱任何这些软件包,我仅限于我的经验和时间来研究这个问题:-)
\n