Открытие всех файлов в папке и применение функции

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

  • Во-первых, мне было интересно, есть ли способ прочитать все файлы в определенной папке прямо в R. Я считаю, что следующая команда перечислит все файлы:

files <- (Sys.glob("*.csv"))

..., который я нашел из Использование R для отображения всех файлов с указанным расширением

Затем следующий код считывает все эти файлы в R.

listOfFiles <- lapply(files, function(x) read.table(x, header = FALSE)) 

... из Манипулирование несколькими файлами в R

Но файлы, кажется, читаются как один непрерывный список, а не отдельные файлы... как я могу изменить script, чтобы открыть все файлы csv в определенной папке в виде отдельных фреймов данных?

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

    Df.1 <- data.frame(A = c(5,4,7,6,8,4),B = (c(1,5,2,4,9,1)))
    Df.2 <- data.frame(A = c(1:6),B = (c(2,3,4,5,1,1)))
    Df.3 <- data.frame(A = c(4,6,8,0,1,11),B = (c(7,6,5,9,1,15)))
    Df.4 <- data.frame(A = c(4,2,6,8,1,0),B = (c(3,1,9,11,2,16)))
    

Я также создал примерную функцию:

Summary<-function(dfile){
SumA<-sum(dfile$A)
MinA<-min(dfile$A)
MeanA<-mean(dfile$A)
MedianA<-median(dfile$A)
MaxA<-max(dfile$A)

sumB<-sum(dfile$B)
MinB<-min(dfile$B)
MeanB<-mean(dfile$B)
MedianB<-median(dfile$B)
MaxB<-max(dfile$B)

Sum<-c(sumA,sumB)
Min<-c(MinA,MinB)
Mean<-c(MeanA,MeanB)
Median<-c(MedianA,MedianB)
Max<-c(MaxA,MaxB)
rm(sumA,sumB,MinA,MinB,MeanA,MeanB,MedianA,MedianB,MaxA,MaxB)

Label<-c("A","B")
dfile_summary<-data.frame(Label,Sum,Min,Mean,Median,Max)
return(dfile_summary)}

Обычно я использовал бы следующую команду для применения функции к каждому отдельному файловому кадру.

Df1.summary < -summary (dfile)

Есть ли способ вместо применения функции ко всем фреймам данных и использовать заголовки данных в сводных таблицах (т.е. Df1.summary).

Большое спасибо,

Katie

Ответ 1

Наоборот, я думаю, что работа с list упрощает автоматизацию таких вещей.

Вот одно решение (я сохранил ваши четыре фрейма данных в папке temp/).

filenames <- list.files("temp", pattern="*.csv", full.names=TRUE)
ldf <- lapply(filenames, read.csv)
res <- lapply(ldf, summary)
names(res) <- substr(filenames, 6, 30)

Важно сохранить полный путь для ваших файлов (как это было в случае с full.names), в противном случае вам нужно вставить рабочий каталог, например.

filenames <- list.files("temp", pattern="*.csv")
paste("temp", filenames, sep="/")

тоже будет работать. Обратите внимание, что я использовал substr для извлечения имен файлов при отбрасывании полного пути.

Вы можете получить доступ к сводным таблицам следующим образом:

> res$`df4.csv`
       A              B        
 Min.   :0.00   Min.   : 1.00  
 1st Qu.:1.25   1st Qu.: 2.25  
 Median :3.00   Median : 6.00  
 Mean   :3.50   Mean   : 7.00  
 3rd Qu.:5.50   3rd Qu.:10.50  
 Max.   :8.00   Max.   :16.00  

Если вы действительно хотите получить отдельные сводные таблицы, вы можете извлечь их впоследствии. Например,

for (i in 1:length(res))
  assign(paste(paste("df", i, sep=""), "summary", sep="."), res[[i]])

Ответ 2

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

plyr находится на кране, и вы можете скачать dostats на https://github.com/halpo/dostats (возможно, с помощью install_github от Hadley devtools)

Предполагая, что у меня есть первые два файла data.frame(Df.1 и Df.2) в csv файлах, вы можете сделать что-то вроде этого.

require(plyr)
require(dostats)

files <- list.files(pattern = ".csv")


for (i in seq_along(files)) {

    assign(paste("Df", i, sep = "."), read.csv(files[i]))

    assign(paste(paste("Df", i, sep = ""), "summary", sep = "."), 
           ldply(get(paste("Df", i, sep = ".")), dostats, sum, min, mean, median, max))

}

Вот вывод

R> Df1.summary
  .id sum min   mean median max
1   A  34   4 5.6667    5.5   8
2   B  22   1 3.6667    3.0   9
R> Df2.summary
  .id sum min   mean median max
1   A  21   1 3.5000    3.5   6
2   B  16   1 2.6667    2.5   5