读取具有不同行数的多个CSV以在文件开头跳过

Lov*_*eow 11 csv r read.table

我必须阅读大约300个单独的CSV.我已设法使用循环和结构化CSV名称自动化该过程.但是,每个CSV在开始时都有14-17行垃圾,并且随机变化,因此在read.table命令中编写'skip'参数的硬编码将不起作用.每个CSV的列名和列数相同.

这是我反对的一个例子:

QUICK STATISTICS:

      Directory: Data,,,,
           File: Final_Comp_Zn_1
      Selection: SEL{Ox*1000+Doma=1201}
         Weight: None,,,
     ,,Variable: AG,,,

Total Number of Samples: 450212  Number of Selected Samples: 277


Statistics

VARIABLE,Min slice Y(m),Max slice Y(m),Count,Minimum,Maximum,Mean,Std.Dev.,Variance,Total Samples in Domain,Active Samples in Domain AG,  
6780.00,   6840.00,         7,    3.0000,   52.5000,   23.4143,   16.8507,  283.9469,        10,        10 AG,   
6840.00,   6900.00,         4,    4.0000,    5.5000,    4.9500,    0.5766,    0.3325,        13,        13 AG,   
6900.00,   6960.00,        16,    1.0000,   37.0000,    8.7625,    9.0047,   81.0848,        29,        29 AG,   
6960.00,   7020.00,        58,    3.0000,   73.5000,   10.6931,   11.9087,  141.8172,       132,       132 AG,   
7020.00,   7080.00,        23,    3.0000,  104.5000,   15.3435,   23.2233,  539.3207,        23,        23 AG,   
7080.00,   7140.00,        33,    1.0000,   15.4000,    3.8152,    2.8441,    8.0892,        35,        35 AG,
Run Code Online (Sandbox Code Playgroud)

基本上我想从线上读VARIABLE,Min slice Y(m),Max slice Y(m),....我可以想到一些解决方案,但我不知道如何编程.无论如何,我可以:

  1. 首先读取CSV并以某种方式计算出有多少行垃圾,然后重新读取并指定要跳过的正确行数?要么
  2. 告诉read.table它在找到列名时开始阅读(因为每个CSV都是相同的)并忽略之前的所有内容?

我认为解决方案(2)是最合适的,但我愿意接受任何建议!

A5C*_*2T1 17

这是一个可以采取的方法的最小例子.

首先,让我们编写一些类似于你描述的csv文件:

cat("blah\nblah\nblah\nVARIABLE,X1,X2\nA,1,2\n", file="myfile1.csv")
cat("blah\nVARIABLE,A1,A2\nA,1,2\n", file="myfile2.csv")
cat("blah\nblah\nVARIABLE,Z1,Z2\nA,1,2\n", file="myfile3.csv")
Run Code Online (Sandbox Code Playgroud)

其次,确定数据的开始位置:

linesToSkip <- sapply(list.files(pattern = "myfile.*.csv"), 
                      function(x) grep("^VARIABLE", readLines(x))-1)
Run Code Online (Sandbox Code Playgroud)

第三,使用该信息将文件读入单个列表.

lapply(names(linesToSkip), 
       function(x) read.csv(file=x, skip = linesToSkip[x]))
# [[1]]
#   VARIABLE X1 X2
# 1        A  1  2
# 
# [[2]]
#   VARIABLE A1 A2
# 1        A  1  2
# 
# [[3]]
#   VARIABLE Z1 Z2
# 1        A  1  2
Run Code Online (Sandbox Code Playgroud)

编辑#1

两次读取数据的替代方法是将其读入列表一次,然后执行相同类型的处理:

myRawData <- lapply(list.files(pattern = "myfile.*.csv"), readLines)
lapply(myRawData, function(x) {
  linesToSkip <- grep("^VARIABLE", x)-1
  read.csv(text = x, skip = linesToSkip)
})
Run Code Online (Sandbox Code Playgroud)

或者,就此而言:

lapply(list.files(pattern = "myfile.*.csv"), function(x) {
  temp <- readLines(x)
  linesToSkip <- grep("^VARIABLE", temp)-1
  read.csv(text = temp, skip = linesToSkip)
})
Run Code Online (Sandbox Code Playgroud)

编辑#2

正如@PaulHiemstra所说,你可以使用参数n只读取每个文件的几行到内存中,而不是读取整个文件.因此,如果您确定每个文件中不超过20行"垃圾",如果您使用的是第一种方法,则可以使用:

linesToSkip <- sapply(list.files(pattern = "myfile.*.csv"), 
                      function(x) grep("^VARIABLE", readLines(x, n = 20))-1)
Run Code Online (Sandbox Code Playgroud)


djh*_*rio 9

freaddata.table中的函数自动检测要跳过的行数.该功能目前处于开发阶段.

这是一个示例代码:

require(data.table)

cat("blah\nblah\nblah\nVARIABLE,X1,X2\nA,1,2\n", file="myfile1.csv")
cat("blah\nVARIABLE,A1,A2\nA,1,2\n", file="myfile2.csv")
cat("blah\nblah\nVARIABLE,Z1,Z2\nA,1,2\n", file="myfile3.csv")

lapply(list.files(pattern = "myfile.*.csv"), fread)
Run Code Online (Sandbox Code Playgroud)