একটি ফোল্ডারে সমস্ত ফাইল পড়ুন এবং প্রতিটি ডেটা ফ্রেমে একটি ফাংশন প্রয়োগ করুন


90

আমি একটি ফোল্ডারে একটি নির্দিষ্ট ফোল্ডারের সমস্ত ফাইলগুলিতে একটি ফাংশন রেখেছি এমন একটি অপেক্ষাকৃত সহজ টুকরো করছি। আমি ভাবছিলাম যে কারও কাছে আমার কাছে বেশ কয়েকটি বিভিন্ন ফোল্ডারে প্রক্রিয়াটি স্বয়ংক্রিয় করতে সহায়তা করার কোনও টিপস রয়েছে কিনা।

  1. প্রথমত, আমি ভাবছিলাম যে কোনও নির্দিষ্ট ফোল্ডারের সমস্ত ফাইল সোজা আর-তে পড়ার উপায় ছিল কিনা আমি বিশ্বাস করি যে নিম্নলিখিত কমান্ডটি সমস্ত ফাইল তালিকাভুক্ত করবে:

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

... যা আমি আর ব্যবহার করে খুঁজে পেয়েছি একটি নির্দিষ্ট এক্সটেনশন সহ সমস্ত ফাইলের তালিকা করতে

এবং তারপরে নীচের কোডটি সেই সমস্ত ফাইল আরে পড়ে reads

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

আর এ একাধিক ফাইল ম্যানিপুলেট করা থেকে

তবে ফাইলগুলি একক ধারাবাহিক তালিকার মতো পড়েও পৃথক ফাইল নয় বলে মনে হয়… আমি কীভাবে কোনও নির্দিষ্ট ফোল্ডারে সমস্ত সিএসভি ফাইল স্বতন্ত্র ডেটাফ্রেম হিসাবে খোলার জন্য স্ক্রিপ্টটি পরিবর্তন করতে পারি?

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

আমি প্রতিটি স্বতন্ত্র ডাটাফ্রেমে ফাংশনটি প্রয়োগ করতে সাধারণত নিম্নলিখিত কমান্ডটি ব্যবহার করব।

ডিএফ 1.সামারী <-সুমারী (ডিফিল)

সমস্ত ডেটাফ্রেমে ফাংশনটি প্রয়োগ করার পরিবর্তে এবং সংক্ষিপ্ত সারণিতে ডেটাফ্রেমগুলির শিরোনামগুলি (যেমন Df1.summary) ব্যবহার করার উপায় আছে কি?

অনেক ধন্যবাদ,

কেটি

উত্তর:


104

বিপরীতে, আমি মনে করি যে এগুলির সাথে কাজ 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]])

4
+1 আমি পুরো নামগুলি সংরক্ষণ করার পরিবর্তে plyr::llply(বা ldply) lapplyনিজের সারসংক্ষেপ ফাংশনটি সংজ্ঞায়িত করব, যেমনplyr::each(min, max, mean, sd, median)
ব্যাপটিস্ট

+1 @ সিএইচএল: list.files ফাংশনটির পুরো নামগুলির কৌশলটির জন্য ধন্যবাদ .... আমি আমার উত্তরে এটি ভুলে গেছি !!!
ডিকোয়া

@ ব্যাপটিস্ট (+1) plyrপরামর্শ দেওয়ার জন্য ধন্যবাদ ।
chl

ধন্যবাদ @ চিএল আমি যে ফাংশনটি লিখেছি তার সাথে উপরের কোডটি কীভাবে ব্যবহার করব? আমি উপরে ("সংক্ষিপ্তর") সমষ্টি, গড়, মধ্যমা ইত্যাদির সাথে উদাহরণের ফাংশনটি ব্যবহার করেছি যা আমি দ্রুত তৈরির একটি উদাহরণ হিসাবে ব্যবহৃত হয়েছিল - আমার আসল বিশ্লেষণের জন্য আমি যে আসল ফাংশনটি ব্যবহার করছি তা আরও জটিল। একই পৃথক সংক্ষিপ্তসার টেবিলগুলি দেওয়ার জন্য আমি কীভাবে উপরের কোডটিতে আরও জটিল ফাংশন অন্তর্ভুক্ত করব তার কোনও ধারণা? -
T_1

@ কেটি আমার ধারণা আপনি আপনার summaryকোনও ফাংশন দিয়ে প্রতিস্থাপন করতে পারবেন , তবে এটি ডেটা নিলে যুক্তি হিসাবে ফ্রেম (এবং / অথবা orচ্ছিক পরামিতিগুলি পার্থক্য ডিএফগুলি জুড়ে স্থির থাকে)। উদাহরণস্বরূপ, lapply(ldf, function(x) apply(x, 2, function(x) c(mean(x), sd(x))))ফিরে আসবে এবং এসডি কোলওয়্যার গণিত।
chl

16

সাধারণত আমি আর এ লুপের জন্য ব্যবহার করি না তবে লুপ এবং দুটি প্যাকেজ ব্যবহার করে আমার সমাধানটি এখানে দেওয়া হয়েছে: প্লাইয়ার এবং ডসস্ট্যাটস

plyr Cran উপর এবং আপনি ডাউনলোড করতে পারেন dostats উপর https://github.com/halpo/dostats (install_github ব্যবহার করে থাকতে পারেন হ্যাডলি থেকে DevTools প্যাকেজ)

ধরে নিলাম সিএসভি ফাইলে আমার আপনার প্রথম দুটি ডাটা.ফ্রেম (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

4
আপনার উত্তরগুলির জন্য @ ডিকোয়া ধন্যবাদ। আমি যে ফাংশনটি তৈরি করেছি ("সংক্ষিপ্তসার") এটি খারাপভাবে বর্ণনা করা হয়েছে। আমি এটি কেবল উদাহরণস্বরূপ উদ্দেশ্যে ব্যবহার করছিলাম - আমার আসল ফাংশনটি আরও জটিল তাই আমি ভাবছিলাম যে উপরের কোডটি (এবং সম্ভবত আমার ফাংশন) কীভাবে পরিবর্তন করা যেতে পারে যাতে এটি সমস্ত বিভিন্ন ডেটা ফ্রেমের জন্য প্রয়োগ করা হয় (এবং ঠিক না আর-এ অন্তর্নির্মিত ফাংশনগুলি ব্যবহার করুন।
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.