R导入具有不同初始行数的文件以跳过

R Import files with differing number of initial rows to skip

我需要将许多文件读入 R,做一些清理,然后将它们组合成一个数据框。文件基本上都是这样开头的:

=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2016.07.11 09:47:35 =~=~=~=~=~=~=~=~=~=~=~=
up
Upload #18
Reader: S1  Site: AA
--------- upload 18 start ---------
Type,Date,Time,Duration,Type,Tag ID,Ant,Count,Gap
E,2016-07-05,11:45:44.17,"upload 17 complete"
D,2016-07-05,11:46:24.69,00:00:00.87,HA,900_226000745055,A2,8,1102
D,2016-07-05,11:46:43.23,00:00:01.12,HA,900_226000745055,A2,10,143

第 headers 列的行是 "Type,Date,Time,Duration,Type,Tag ID,Ant,Count,Gap"。数据应该有 9 列。问题是 header 字符串上方的行数对于每个文件都是不同的,所以我不能简单地使用 skip = 5。我也只需要以 "D," 开头的行,其他都是消息,不是数据。

读取文件的最佳方式是什么,确保我有 9 列并跳过所有垃圾?
我一直在使用 readr() 包中的 read_csv 函数,因为到目前为止它产生的格式问题最少。但是,我对任何新想法都持开放态度,包括一种只阅读以 "D," 开头的行的方法。我试过使用 read.tableskip = grep("Type," readLines(i)),但它似乎没有正确找到 header 字符串。这是我的基本代码:

dataFiles <- Sys.glob("*.*")
datalist <- list()
for (i in dataFiles) {
 d01 <- read_csv(i, col_names = F, na = "NA", skip = 35)  
 # do clean-up stuff
 datalist[[i]] <- d 
}

如果您的 header 行始终以单词 Type 开头,您可以简单地从初始读取中省略 skip 选项,然后删除 [=18] 之前的任何行=]行。下面是一些帮助您入门的代码(未测试):

dataFiles <- Sys.glob("*.*")
datalist <- list()
for (i in dataFiles) {
 d01 <- read_csv(i, col_names = F, na = "NA")
 headerRow <- which( d01[,1] == 'Type' )
 d01 <- d01[headerRow+1,] # This keeps all rows after the header row.  
 # do clean-up stuff
 datalist[[i]] <- d 
}

如果你想保留header,你可以使用:

for (i in dataFiles) {
 d01 <- read_csv(i, col_names = F, na = "NA")
 headerRow <- which( d01[,1] == 'Type' )
 d01 <- d01[headerRow+1,]  # This keeps all rows after the header row.
 header <- d01[headerRow,] # Get names from header row.
 setNames( d01, header )   # Assign names.
 # do clean-up stuff
 datalist[[i]] <- d 
}

您可以使用自定义函数遍历每个文件,并仅过滤 type 列中以 D 开头的文件,并在末尾将它们全部绑定在一起。如果您希望将它们作为单独的列表,请删除 bind_rows

load_data <-function(path) {
  require(dplyr)
  setwd(path)
  files <- dir()
  read_files <- function(x) {
    data_file <- read.csv(paste(path, "/", x, ".csv", sep = ""), stringsAsFactors = FALSE, na.strings=c("","NA"))
    row.number <- grep("^Type$", data_file[,1])
    colnames(data_file) <- data_file[row.number,]
    data_file <- data_file[-c(1:row.number+1),]
    data_file <- data_file %>%
      filter(grepl("^D", Type))
    return(data_file)
  }
  data <- lapply(files, read_files)
}

list_of_file <- bind_rows(load_data("YOUR_FOLDER_PATH"))

另一个基本的 R 解决方案如下:您按行读入文件,获取以 "D" 和 header 行开头的行的索引。之后,您只需将这些行用“,”分隔并将其放入 data.frame 并将 header 行中的名称分配给它。

lines <- readLines(i)
dataRows <- grep("^D,", lines)

names <- unlist(strsplit(lines[grep("Type,", lines)], split = ","))

data <- as.data.frame(matrix(unlist(strsplit(lines[dataRows], ",")), nrow = length(dataRows), byrow=T))
names(data) <- names

输出:

    Type       Date        Time    Duration Type           Tag ID Ant Count  Gap
1      D 2016-07-05 11:46:24.69 00:00:00.87   HA 900_226000745055  A2     8 1102
2      D 2016-07-05 11:46:43.23 00:00:01.12   HA 900_226000745055  A2    10  143