【问题标题】:R Import files with differing number of initial rows to skipR导入具有不同初始行数的文件以跳过
【发布时间】:2017-09-14 15:28:10
【问题描述】:

我需要将许多文件读入 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

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

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

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 
}

【问题讨论】:

  • type 列中的值d 是否一致?
  • 您能否使用可重现的数据重新处理您的问题,以便其他人可以测试它?原则上,您走在正确的道路上,因为这是一个可以通过读取数据子集(使用 read_csv 中的 n_max 参数)作为临时数据并使用 grep 存储索引来解决的问题为每个数据文件跳过适当的行数。
  • 是的@D.sen,D 总是在Type 列中。
  • 看起来我的文件中标题行上方有时有几行读取"Type 'HE' for help"。这会导致任何搜索 "Type" 的解决方案都失败。谁能告诉我正确的正则表达式来搜索仅包含单词“Type”而没有其他字符的行? @D.sen、@bmosov01、@You-lee?
  • 像 You-leee 在他们的grep 中那样包含, 怎么样。即Type,?

标签: r for-loop import skip


【解决方案1】:

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

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

【讨论】:

  • 这是最干净、最简单的解决方案,因为出现了意想不到的奇怪格式问题。感谢 bmosov01 和 D.sen 提供的有用选项。
【解决方案2】:

您可以使用自定义函数循环遍历每个文件,并仅过滤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"))

【讨论】:

    【解决方案3】:

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

    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 
    }
    

    如果要保留标题,可以使用:

    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 
    }
    

    【讨论】:

      猜你喜欢
      • 2018-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-15
      • 2016-09-18
      • 2012-09-02
      • 2020-06-20
      • 1970-01-01
      相关资源
      最近更新 更多