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

当数据结构发生变化时,如何在R中合并多个文本文件?,r,text,merge,timestamp,R,Text,Merge,Timestamp,我正在尝试将多个文本文件合并到一个数据文件中,但前几行和后几行的数据结构与我的其余部分不同。我想用这种结构组合多个文件。这样做,我还想在整个数据集上插入在文件两端给出的时间戳 第一个问题是在尝试导入数据时出现的,我到目前为止已经尝试过了: file_list <- list.files() for (file in file_list) { # if the merged dataset doesn't exist, create it if (!exists('dataset')

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

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

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)
  }
}

有人知道怎么做吗?

datasetA
tidyverse
选项:

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

  • 通过跳过第一行并绑定数据集来读取文件。我发现
    purr::map(read_csv)
    purr::reduce(bind_rows)
    更适合循环

  • 添加一个名为
    is\u metadata
    的逻辑列

  • NA
    值中填入in
    是元数据

  • 筛选行
一种带有
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
                # ...
                # ...
库(tidyverse)
图书馆(stringr)
文件列表%
映射(读取csv,跳过=1)%>%
减少(绑定_行)%>%
重命名(X1=`mmho/cm`)%>%#为简单起见,重命名该列
mutate(is_metadata=if_else(
条件=str|u检测(X1,“轮廓旋转”),
真=X1,
false=NA_character)%>%#设置X1的相同列类
tidyr::fill(是元数据,.direction=“up”)%%>%
过滤器(!is.na(Celcius))%>%
#时间戳的附加处理
# ...
# ...

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

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)
库(data.table)

file_list是所有文件中相同的行数吗?您在这里只读取第一个文件中的一行,一旦创建数据集,其余文件将被跳过。无论如何,我看不出有任何理由将其返回给变量,也不记得list.files()接受一个块来执行,所以我怀疑这是否真的是导致错误的原因。(由于在别处定义了变量,它可能在随机情况下起作用,而您在这里没有显示这些变量)@Roland,例如,不同文件的行数不同(关于该主题还有许多其他SO问题)
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)