当数据结构变化时,如何合并R中的多个文本文件?

时间:2018-05-25 11:05:19

标签: r text merge timestamp

我正在尝试将多个文本文件合并到一个数据文件中,但前几行和最后几行与我file的其余部分没有相同的数据结构。我想将多个文件与这种类型的结构组合在一起。这样做,我还想在整个数据集中插入文件每一端给出的时间戳。

尝试导入数据时出现了第一个问题,到目前为止我尝试过:

file_list <- list.files()
for (file in file_list) {
  # if the merged dataset doesn't exist, create it
  if (!exists('dataset')) {
    dataset <- read.table(file, sep = ';', skip = 6, nrow = length(readLines(file)) - 4 -6)
  }
  # if the merged dataset does exist, append to it
  if (exists('dataset')) {
    temp_dataset <- read.table(file, sep = ';', skip = 6, nrow = length(readLines(file)) - 4 - 6)
    dataset <- rbind(dataset, temp_dataset)
    rm(temp_dataset)
  }
}

但后来我收到以下错误消息:

Error in rbind(deparse.level, ...) : 
  numbers of columns of arguments do not match

有谁知道怎么做?

3 个答案:

答案 0 :(得分:0)

    dataset <- read.table(
          file, 
          sep = ',', 
          skip = 6, 
          nrow = length(readLines(file)) - 4 - 6
          )

答案 1 :(得分:0)

tidyverse选项:

步骤

  • 通过跳过第一行并绑定数据集来读取文件。我找到了 purrr::map(read_csv)purrr::reduce(bind_rows)优于for循环。

  • 添加名为is_metadata的逻辑列。

  • 使用in填充NAis_metadata列。

  • 过滤行

tidyverse的一个解决方案:

library(tidyverse)
library(stringr)
file_list <- list.files()
file_list %>% 
                map(read_csv, skip = 1) %>% 
                reduce(bind_rows) %>% 
                rename(X1 = `mmho/cm`) %>% # rename the column for simplicity
                mutate(is_metadata = if_else(
                                condition = str_detect(X1, "Profile|turned"),
                                true = X1,
                                false = NA_character_)) %>% # set the same column class of X1
                tidyr::fill(is_metadata, .direction = "up") %>% 
                filter(!is.na(Celcius)) %>% 
                # additional processing for timestamp
                # ...
                # ...

答案 2 :(得分:0)

关于我们如何设法合并所有数据文件并获取时间戳的完整代码:

library(data.table)

file_list <- list.files()                       #list all the files in the directory
datalist <- vector('list', length(file_list))   #create datalist
timelist <- vector('list', length(file_list))   #create timelist

#create for-loop
#read data
#read time
#separate time
#define start- and endtime
#define time difference
#define time interval
#create vector with timestamps
#add timestamps to existing datafile

for (i in 1:length(file_list)) {
  datalist[[i]] <- read.table(file_list[i], sep = ',', skip = 6, nrow = length(readLines(file_list[i]))-4-6, stringsAsFactors = FALSE)
  timelist[[i]] <- read.table(file_list[i], sep = ',', skip = length(readLines(file_list[i]))-2, stringsAsFactors = FALSE)
  timelist[[i]][1,1] <- gsub('  CTD turned on at ', '', timelist[[i]][1,1])
  timelist[[i]][2,1] <- gsub('  CTD turned off at ', '', timelist[[i]][2,1])
  starttime <- strptime(timelist[[i]][1,1], format = '%m/%d/%Y %H:%M:%S')
  endtime <- strptime(timelist[[i]][2,1], format = '%m/%d/%Y %H:%M:%S')
  diff <- difftime(endtime, starttime, unit = 's')
  int <- diff/(nrow(datalist[[i]]) - 1)
  extratime <- seq(starttime, endtime, by = int)
  datalist[[i]] <- cbind(datalist[[i]], extratime)
  print(i)
}

dt1 <- rbindlist(datalist)
dt2 <- as.data.frame(dt1)
colnames(dt2) <- c('mmho/cm', 'celcius', 'dbars', 'hz', 'datetime')

write.table(dt2, 'M1traveller.csv', quote = FALSE, sep = ',', row.names = FALSE)