2016-04-24 2 views
2

После поиска помощи в разных потоках по этой теме я по-прежнему не стал мудрее. Поэтому: Здесь возникает еще один вопрос о циклическом перемещении нескольких файлов данных ...Средние значения от нескольких кадров csv до данных

OK. У меня есть несколько файлов CSV в одной папке, содержащей 5 столбцов данных. Имена файлов следующим образом:

Влажный ггггммдд hh_mm_ss.csv

Я хотел бы создать сценарий, который считывает обрабатывает CSV-файлы один за другим делать следующие шаги:

1) загрузить файл 2) проверить количество строк и исключить файл, если менее 3 регистраций 3) рассчитать среднее значение всех измерений (= строк) для столбца 2 4) рассчитать среднее значение всех измерений (= строк) для столбца 4 5) выход временная метка имени файла, средняя колонка 2 и средняя колонка 4 для кадра данных,

я написал следующую функцию

moist.each.mean <- function() { 
    library("tcltk") 
    directory <- tk_choose.dir("","Choose folder for Humidity data files") 
    setwd(directory) 
    filelist <- list.files(path = directory) 
    filetitles <- regmatches(filelist, regexpr("[0-9].*[0-9]", filelist)) 
    mdf <- data.frame(timestamp=character(), humidity=numeric(), temp=numeric()) 

    for(i in 1:length(filelist)){ 
    file.in[[i]] <- read.csv(filelist[i], header=F) 
    if (nrow(file.in[[i]]<3)){ 
     print("discard") 
    } else { 
     newrow <- c(filetitles[[i]], round(mean(file.in[[i]]$V2),1), round(mean(file.in[[i]]$V4),1)) 
     mdf <- rbind(mdf, newrow) 
    } 
    } 
    names(mdf) <- c("timestamp", "humidity", "temp") 
} 

, но я получаю сообщение об ошибке:

Error in `[[<-.data.frame`(`*tmp*`, i, value = list(V1 = c(10519949L, : 
    replacement has 18 rows, data has 17 

Есть идеи?

Thx, kruemelprinz

+0

где указано 'file.in'? –

+0

Я не знаю, как его определить, к сожалению. Я уже много изо всех сил пытался зайти так далеко ... file.in предназначен для временного объекта для загрузки в определенном csv, пока он не будет перезаписан следующим обрабатываемым файлом. – kruemelprinz

ответ

0

Я также предлагаю использовать (л) применять ... Вот мое мнение:

getMeans <- function(fpath,runfct, 
       target_cols = c(2), 
       sep=",", 
       dec=".", 
       header = T, 
       min_obs_threshold = 3){ 

< е - list.files (FPATH) fcsv < - е [grepl ("\ CSV", е)]

fcsv <- paste0(fpath,fcsv) 

csv_list <- lapply(fcsv,read.table,sep = sep, 
       dec = dec, header = header) 

csv_rows <- sapply(csv_list,nrow) 

rel_csv_list <- csv_list[!(csv_rows < min_obs_threshold)] 

lapply(rel_csv_list,function(x) colMeans(x[,target_cols])) 


} 

Кроме того, с такого рода сообщения об ошибке, отладчик может быть очень полезным. Просто запустите debug(moist.each.mean) и выполните функцию поэтапно.

0

Вот несколько иной подход. Используйте lapply для чтения каждого файла csv, при необходимости исключите его, иначе создайте сводку. Это дает вам список, где каждый элемент представляет собой сводку фреймов данных. Затем используйте rbind для создания окончательного сводного кадра данных.

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

# Get vector of filenames to read 
filelist=list.files(path=directory, pattern="csv") 

# Read all the csv files into a list and create summaries 
df.list = lapply(filelist, function(f) { 

    file.in = read.csv(f, header=TRUE, stringsAsFactors=FALSE) 

    # Set to empty data frame if file has less than 3 rows of data 
    if (nrow(file.in) < 3) { 

    print(paste("Discard", f)) 

    # Otherwise, capture file timestamp and summarise data frame 
    } else { 

    data.frame(timestamp=substr(f, 7, 22), 
       humidity=round(mean(file.in$V2),1), 
       temp=round(mean(file.in$V4),1)) 
    } 
}) 

# Bind list into final summary data frame (excluding the list elements 
# that don't contain a data frame because they didn't have enough rows 
# to be included in the summary) 
result = do.call(rbind, df.list[sapply(df.list, is.data.frame)]) 

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

c(filetitles[[i]], round(mean(file.in[[i]]$V2),1), round(mean(file.in[[i]]$V4),1)) является вектором с тремя элементами. То, что вы на самом деле хотите это кадр данных с тремя колонками:

data.frame(timestamp=filetitles[[i]], 
      humidity=round(mean(file.in[[i]]$V2),1), 
      temp=round(mean(file.in[[i]]$V4),1)) 
0

Спасибо за предложения, используя lapply. Это определенно ценно, так как это экономит много кода!В то же время, мне удалось исправить мой исходный код, а также:

library("tcltk") 
# directory: path to csv files 
directory <- 
    tk_choose.dir("","Choose folder for Humidity data files") 
setwd(directory) 
filelist <- list.files(path = directory) 
filetitles <- 
    regmatches(filelist, regexpr("[0-9].*[0-9]", filelist)) 
mdf <- data.frame() 

for (i in 1:length(filelist)) { 
    file.in <- read.csv(filelist[i], header = F, skipNul = T) 
    if (nrow(file.in) < 3) { 
    print("discard") 
    } else { 
    newrow <- 
     matrix(
     c(filetitles[[i]], round(mean(file.in$V2, na.rm=T),1), round(mean(file.in$V4, na.rm=T),1)), nrow = 1, ncol = 
      3, byrow = T 
    ) 
    mdf <- rbind(mdf, newrow) 
    } 
} 

names(mdf) <- c("timestamp", "humidity", "temp") 

Только я не получил его на работу в качестве функции, потому что тогда я бы только одну строку в mdf, содержащий последние данные файла. Так или иначе, он не добавлял строки, но переписывал строку 1 с каждой итерацией. Но использование этого без функции обертки отлично работало ...

Смежные вопросы