Как объединить несколько текстовых файлов в R, когда структура данных меняется? - PullRequest
0 голосов
/ 25 мая 2018

Я пытаюсь объединить несколько текстовых файлов в один файл данных, но первые несколько строк и последние несколько строк не имеют ту же структуру данных, что и остальная часть моего файла .Я хочу объединить несколько файлов с этим типом структуры.При этом я также хотел бы интерполировать временную метку, заданную на каждом конце файла по всему набору данных.

Первые проблемы возникают при попытке импортировать данные, что я пробовал до сих пор:

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 голосов
/ 25 мая 2018

A tidyverse опция:

Шаги

  • Считайте файлы, пропустив первый ряд и связав наборы данных.Я считаю, что
    purrr::map(read_csv) и purrr::reduce(bind_rows) лучше, чем цикл for.

  • Добавьте логический столбец с именем is_metadata.

  • Заполните значения NA в столбце is_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
                # ...
                # ...
0 голосов
/ 06 июня 2018

Ниже приведен полный код того, как нам удалось объединить все файлы данных и получить там временные метки:

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)
0 голосов
/ 25 мая 2018
    dataset <- read.table(
          file, 
          sep = ',', 
          skip = 6, 
          nrow = length(readLines(file)) - 4 - 6
          )
...