对于大型数据集,在R中使用fread()而不是read_table(

g9icjywg  于 2023-02-14  发布在  其他
关注(0)|答案(2)|浏览(138)

我有两个不同的文件夹,"big_data"(一个约2GB的文件)和另一个"small_data"(约6个文件,总共约150 MB)。我想将包含多个标题行和空格的数据文件上载到R。文件的结构如下所示

# File name
#
#@   1  "Some text"                                                   "aa"
#@   2  "Some text"                                                   "bb"
#@   3  "Some text"                                                   "cc"
#@   4  "Some text"                                                   "dd"
#@   5  "Some text"                                                   "ee"
#@   6  "Some text"                                                   "ff"

#
#
#
#

 0.000000e+00  0.000000e+00  0.000000e+00  0.000000e+00  0.000000e+00  0.000000e+00  
 1.000000e-03  3.727051e-04  2.532203e-04  4.736003e-04  3.727051e-07  0.000000e+00   
 2.000000e-03  2.266785e-03  1.540081e-03  2.880429e-03  2.639490e-06  0.000000e+00  
 3.000000e-03  7.538553e-03  5.121786e-03  9.579321e-03  1.017804e-05  0.000000e+00   
 4.000000e-03  1.838835e-02  1.249329e-02  2.336627e-02  2.856639e-05  0.000000e+00  
 5.000000e-03  3.703296e-02  2.516073e-02  4.705817e-02  6.559935e-05  0.000000e+00 
 6.000000e-03  2.266785e-03  1.540081e-03  2.880429e-03  2.639490e-06  0.000000e+00  
 7.000000e-03  7.538553e-03  5.121786e-03  9.579321e-03  1.017804e-05  0.000000e+00   
 8.000000e-03  1.838835e-02  1.249329e-02  2.336627e-02  2.856639e-05  0.000000e+00  
 9.000000e-03  3.703296e-02  2.516073e-02  4.705817e-02  6.559935e-05  0.000000e+00

如您所见,它包含10行和6列。"#@"后面的文本是列名。我编写了以下函数从用户指定的文件夹导入数据。它导入数据,跳过包含标题文本的行,提取列名并删除该文件夹中所有文件的NA列。()如果"用户指定的文件夹"为"small_data"且fread如果"user_specified_folder"为"big_data",则返回()。它适用于前者,但不适用于后者。fread没有错误(),R会话内存约为6 GB,但导入的文件大小仅为15 kB(仅列名)。
x一个一个一个一个x一个一个二个x
如何让上面的代码与fread()一起工作?

x4shl7ld

x4shl7ld1#

下面是我阅读这些文件的方式:

library(data.table)
filename <- 'E:/temp/test.txt'
con <- file(filename)

n <- 0
repeat {
  n <- n + 10
  header <- readLines(con, n)
  test1 <- grepl("#", header, fixed = TRUE)
  test2 <- nchar(header) == 0 #assumes empty lines don't contain whitespace characters
  if (any(!test1 & !test2)) {
    n <- n - sum(!test1 & !test2)
    break
  }
}

close(con)

header <- header[seq_len(n)]
header <- header[nchar(header) > 1]

header <- sub(pattern='[^"]*"[^"]*"[^"]*"', replacement='', header)
header <- gsub('"', '', header)

DT <- fread(file = filename, skip = n, header = FALSE)
setnames(DT, header)

print(DT)
#       aa           bb           cc           dd           ee ff
# 1: 0.000 0.0000000000 0.0000000000 0.0000000000 0.000000e+00  0
# 2: 0.001 0.0003727051 0.0002532203 0.0004736003 3.727051e-07  0
# 3: 0.002 0.0022667850 0.0015400810 0.0028804290 2.639490e-06  0
# 4: 0.003 0.0075385530 0.0051217860 0.0095793210 1.017804e-05  0
# 5: 0.004 0.0183883500 0.0124932900 0.0233662700 2.856639e-05  0
# 6: 0.005 0.0370329600 0.0251607300 0.0470581700 6.559935e-05  0
# 7: 0.006 0.0022667850 0.0015400810 0.0028804290 2.639490e-06  0
# 8: 0.007 0.0075385530 0.0051217860 0.0095793210 1.017804e-05  0
# 9: 0.008 0.0183883500 0.0124932900 0.0233662700 2.856639e-05  0
#10: 0.009 0.0370329600 0.0251607300 0.0470581700 6.559935e-05  0
zz2j4svz

zz2j4svz2#

我建议在fread()中使用cmd-参数,以便在阅读之前预处理文件。
从功能上讲,它使用fread读取shell命令的输出,在本例中,我们使用类似grep的命令(findstr在所有现代Windows(我使用的是W10)版本中都有)只读取我们想要读取的行。
在windows上,它与findstr一起工作,在 *nix环境下,你必须修改下面的代码以使用grepawk
此解决方案可能存在的缺点:根据所选的shell命令,它可能会降低代码在操作系统之间的可移植性。

library(data.table)

# extract the forth column of all lines starting with "#@"
colnames <- fread(cmd = 'findstr "^#@" weird_file.csv', 
                sep = " ", header = FALSE, select = 4)

# extract all lines not startting with a "#" 
mydata <- fread(cmd = 'findstr "^[^#]" weird_file.csv', 
                sep = " ", header = FALSE, col.names = unlist(colnames) )

#       aa           bb           cc           dd           ee ff
# 1: 0.000 0.0000000000 0.0000000000 0.0000000000 0.000000e+00  0
# 2: 0.001 0.0003727051 0.0002532203 0.0004736003 3.727051e-07  0
# 3: 0.002 0.0022667850 0.0015400810 0.0028804290 2.639490e-06  0
# 4: 0.003 0.0075385530 0.0051217860 0.0095793210 1.017804e-05  0
# 5: 0.004 0.0183883500 0.0124932900 0.0233662700 2.856639e-05  0
# 6: 0.005 0.0370329600 0.0251607300 0.0470581700 6.559935e-05  0
# 7: 0.006 0.0022667850 0.0015400810 0.0028804290 2.639490e-06  0
# 8: 0.007 0.0075385530 0.0051217860 0.0095793210 1.017804e-05  0
# 9: 0.008 0.0183883500 0.0124932900 0.0233662700 2.856639e-05  0
#10: 0.009 0.0370329600 0.0251607300 0.0470581700 6.559935e-05  0

使用的示例数据

相关问题