폴더의 모든 파일을 읽고 각 데이터 프레임에 기능 적용


90

특정 폴더의 모든 파일에 대해 함수에 넣은 비교적 간단한 분석을 수행하고 있습니다. 많은 다른 폴더에서 프로세스를 자동화하는 데 도움이되는 팁이 있는지 궁금합니다.

  1. 첫째, 특정 폴더의 모든 파일을 R로 직접 읽는 방법이 있는지 궁금합니다. 다음 명령이 모든 파일을 나열 할 것이라고 생각합니다.

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

... 내가 찾은 R을 사용하여 지정된 확장자를 가진 모든 파일을 나열했습니다.

그리고 다음 코드는 모든 파일을 R로 읽습니다.

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

…에서 R에서 여러 파일 조작에서

그러나 파일은 개별 파일이 아닌 하나의 연속 목록으로 읽는 것 같습니다. 특정 폴더의 모든 csv 파일을 개별 데이터 프레임으로 열도록 스크립트를 어떻게 변경할 수 있습니까?

  1. 둘째, 모든 파일을 개별적으로 읽을 수 있다고 가정하면 이러한 모든 데이터 프레임에서 한 번에 함수를 완료하려면 어떻게해야합니까? 예를 들어, 원하는 것을 설명 할 수 있도록 4 개의 작은 데이터 프레임을 만들었습니다.

    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)에서 데이터 프레임의 제목을 사용하는 방법이 있습니까?

감사합니다.

케이티

답변:


104

반대로 작업을 list하면 이러한 작업을 쉽게 자동화 할 수 있다고 생각 합니다.

여기에 하나의 솔루션이 있습니다 (폴더에 4 개의 데이터 프레임을 저장했습니다 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]])

3
+1 이름을 전체적으로 보존하는 대신에 plyr::llply(또는 ldply) lapply내 자신의 요약 기능을 정의합니다. 예plyr::each(min, max, mean, sd, median)
baptiste

+1 @chl : list.files 함수의 fullnames 트릭에 감사드립니다 .... 내 대답에서 잊어 버렸습니다 !!!
dickoa

@baptiste (+1) plyr제안 해 주셔서 감사합니다 .
chl

감사합니다 @chl. 내가 작성한 함수로 위 코드를 어떻게 사용합니까? 합계, 평균, 중앙값 등과 함께 위에서 사용한 예제 함수 ( "요약")는 방금 만든 예제로 사용되었습니다. 실제 분석에 사용하는 실제 함수는 훨씬 더 복잡합니다. 동일한 개별 요약 테이블을 제공하기 위해 더 복잡한 함수를 위의 코드에 통합하는 방법에 대한 아이디어가 있습니까? –
KT_1

@Katie 인수로 data.frame을 사용 summary하는 경우 (및 / 또는 차이 DF에서 일정한 선택적 매개 변수) 당신의 모든 기능으로 바꿀 수 있다고 생각합니다 . 예를 들어 lapply(ldf, function(x) apply(x, 2, function(x) c(mean(x), sd(x))))평균을 반환하고 SD는 colwise로 계산됩니다.
chl

16

일반적으로 R에서 for 루프를 사용하지 않지만 여기에 for 루프와 두 개의 패키지를 사용하는 솔루션이 있습니다 : plyrdostats

plyr 는 cran에 있으며 https://github.com/halpo/dostats에서 dostats 를 다운로드 할 수 있습니다 (Hadley devtools 에서 install_github를 사용할 수 있음). 패키지 ).

csv 파일에 처음 두 개의 data.frame (Df.1 및 Df.2)이 있다고 가정하면 다음과 같이 할 수 있습니다.

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

(+1) 우리가 동시에 대답 한 것 같고 귀하의 plyr솔루션은 상당히 좋습니다!
chl

1
귀하의 답변에 대해 @dickoa에게 감사드립니다. 내가 구성한 기능 ( "요약")은 제대로 설명되지 않았습니다. 저는 단지 설명을 목적으로 사용하고있었습니다. 제 실제 함수는 훨씬 더 복잡해서 위의 코드 (그리고 아마도 제 함수)가 모든 다른 데이터 프레임에 적용되도록 어떻게 변경 될 수 있는지 궁금합니다. R에서 내장 함수를 사용하십시오).
KT_1

2

다음은 tidyverse가장 우아하지는 않지만 요약에 포함 된 내용과 관련하여 약간의 유연성을 제공 하는 옵션입니다.

library(tidyverse)
dir_path <- '~/path/to/data/directory/'
file_pattern <- 'Df\\.[0-9]\\.csv' # regex pattern to match the file name format

read_dir <- function(dir_path, file_name){
  read_csv(paste0(dir_path, file_name)) %>% 
    mutate(file_name = file_name) %>%                # add the file name as a column              
    gather(variable, value, A:B) %>%                 # convert the data from wide to long
    group_by(file_name, variable) %>% 
    summarize(sum = sum(value, na.rm = TRUE),
              min = min(value, na.rm = TRUE),
              mean = mean(value, na.rm = TRUE),
              median = median(value, na.rm = TRUE),
              max = max(value, na.rm = TRUE))
  }

df_summary <- 
  list.files(dir_path, pattern = file_pattern) %>% 
  map_df(~ read_dir(dir_path, .))

df_summary
# A tibble: 8 x 7
# Groups:   file_name [?]
  file_name variable   sum   min  mean median   max
  <chr>     <chr>    <int> <dbl> <dbl>  <dbl> <dbl>
1 Df.1.csv  A           34     4  5.67    5.5     8
2 Df.1.csv  B           22     1  3.67    3       9
3 Df.2.csv  A           21     1  3.5     3.5     6
4 Df.2.csv  B           16     1  2.67    2.5     5
5 Df.3.csv  A           30     0  5       5      11
6 Df.3.csv  B           43     1  7.17    6.5    15
7 Df.4.csv  A           21     0  3.5     3       8
8 Df.4.csv  B           42     1  7       6      16

매우 유연하므로 훌륭한 솔루션입니다. 내 데이터 형식 read_csv()이 제대로 작동하지 않아 data.table::fread().
Thorsten
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.