एक त्वरित और संक्षिप्त tidyverse
समाधान: ( बेस आर के दोगुने से अधिक तेज read.csv
)
tbl <-
list.files(pattern = "*.csv") %>%
map_df(~read_csv(.))
और data.table का fread()
लोड समय फिर से आधा हो सकता है। (1/4 बेस आर बार के लिए)
library(data.table)
tbl_fread <-
list.files(pattern = "*.csv") %>%
map_df(~fread(.))
stringsAsFactors = FALSE
तर्क dataframe कारक मुक्त रहता है, (और marbel अंक बाहर के रूप में, के लिए डिफ़ॉल्ट सेटिंग है fread
)
यदि टाइपकास्टिंग चुटीली हो रही है, तो आप सभी स्तंभों को col_types
तर्क के साथ वर्ण के रूप में बाध्य कर सकते हैं ।
tbl <-
list.files(pattern = "*.csv") %>%
map_df(~read_csv(., col_types = cols(.default = "c")))
यदि आप अपनी फ़ाइलों की सूची को अंततः बांधने के लिए उपनिर्देशिका में डुबकी लगाना चाहते हैं, तो पथ नाम शामिल करना सुनिश्चित करें, साथ ही साथ अपनी सूची में उनके पूर्ण नामों के साथ फ़ाइलों को पंजीकृत करें। यह बाध्यकारी कार्य को वर्तमान निर्देशिका के बाहर जाने की अनुमति देगा। (निर्देशिका 'सीमाओं' पर वापस जाने की अनुमति देने के लिए पासपोर्ट की तरह संचालन के रूप में पूर्ण मार्ग के बारे में सोचना।)
tbl <-
list.files(path = "./subdirectory/",
pattern = "*.csv",
full.names = T) %>%
map_df(~read_csv(., col_types = cols(.default = "c")))
जैसा कि हेडली ने यहाँ वर्णन किया है (लगभग आधा नीचे):
map_df(x, f)
प्रभावी रूप से के रूप में ही है do.call("rbind", lapply(x, f))
....
बोनस फ़ीचर - नीचे दिए गए टिप्पणियों में रिकॉर्ड में फ़ीचर अनुरोध में फ़ाइल नाम जोड़ना:
* filename
प्रत्येक रिकॉर्ड में मूल जोड़ें ।
कोड समझाया गया: तालिकाओं के प्रारंभिक पढ़ने के दौरान प्रत्येक रिकॉर्ड के लिए फ़ाइलनाम को जोड़ने के लिए एक फ़ंक्शन बनाएं। फिर साधारण read_csv()
फंक्शन के बजाय उस फंक्शन का उपयोग करें ।
read_plus <- function(flnm) {
read_csv(flnm) %>%
mutate(filename = flnm)
}
tbl_with_sources <-
list.files(pattern = "*.csv",
full.names = T) %>%
map_df(~read_plus(.))
(टाइपकास्टिंग और सबडायरेक्ट हैंडलिंग एप्रोच read_plus()
को उसी तरीके से फ़ंक्शन के अंदर भी हैंडल किया जा सकता है, जैसा कि ऊपर दिए गए दूसरे और तीसरे वेरिएंट में सचित्र है।)
### Benchmark Code & Results
library(tidyverse)
library(data.table)
library(microbenchmark)
### Base R Approaches
#### Instead of a dataframe, this approach creates a list of lists
#### removed from analysis as this alone doubled analysis time reqd
# lapply_read.delim <- function(path, pattern = "*.csv") {
# temp = list.files(path, pattern, full.names = TRUE)
# myfiles = lapply(temp, read.delim)
# }
#### `read.csv()`
do.call_rbind_read.csv <- function(path, pattern = "*.csv") {
files = list.files(path, pattern, full.names = TRUE)
do.call(rbind, lapply(files, function(x) read.csv(x, stringsAsFactors = FALSE)))
}
map_df_read.csv <- function(path, pattern = "*.csv") {
list.files(path, pattern, full.names = TRUE) %>%
map_df(~read.csv(., stringsAsFactors = FALSE))
}
### *dplyr()*
#### `read_csv()`
lapply_read_csv_bind_rows <- function(path, pattern = "*.csv") {
files = list.files(path, pattern, full.names = TRUE)
lapply(files, read_csv) %>% bind_rows()
}
map_df_read_csv <- function(path, pattern = "*.csv") {
list.files(path, pattern, full.names = TRUE) %>%
map_df(~read_csv(., col_types = cols(.default = "c")))
}
### *data.table* / *purrr* hybrid
map_df_fread <- function(path, pattern = "*.csv") {
list.files(path, pattern, full.names = TRUE) %>%
map_df(~fread(.))
}
### *data.table*
rbindlist_fread <- function(path, pattern = "*.csv") {
files = list.files(path, pattern, full.names = TRUE)
rbindlist(lapply(files, function(x) fread(x)))
}
do.call_rbind_fread <- function(path, pattern = "*.csv") {
files = list.files(path, pattern, full.names = TRUE)
do.call(rbind, lapply(files, function(x) fread(x, stringsAsFactors = FALSE)))
}
read_results <- function(dir_size){
microbenchmark(
# lapply_read.delim = lapply_read.delim(dir_size), # too slow to include in benchmarks
do.call_rbind_read.csv = do.call_rbind_read.csv(dir_size),
map_df_read.csv = map_df_read.csv(dir_size),
lapply_read_csv_bind_rows = lapply_read_csv_bind_rows(dir_size),
map_df_read_csv = map_df_read_csv(dir_size),
rbindlist_fread = rbindlist_fread(dir_size),
do.call_rbind_fread = do.call_rbind_fread(dir_size),
map_df_fread = map_df_fread(dir_size),
times = 10L)
}
read_results_lrg_mid_mid <- read_results('./testFolder/500MB_12.5MB_40files')
print(read_results_lrg_mid_mid, digits = 3)
read_results_sml_mic_mny <- read_results('./testFolder/5MB_5KB_1000files/')
read_results_sml_tny_mod <- read_results('./testFolder/5MB_50KB_100files/')
read_results_sml_sml_few <- read_results('./testFolder/5MB_500KB_10files/')
read_results_med_sml_mny <- read_results('./testFolder/50MB_5OKB_1000files')
read_results_med_sml_mod <- read_results('./testFolder/50MB_5OOKB_100files')
read_results_med_med_few <- read_results('./testFolder/50MB_5MB_10files')
read_results_lrg_sml_mny <- read_results('./testFolder/500MB_500KB_1000files')
read_results_lrg_med_mod <- read_results('./testFolder/500MB_5MB_100files')
read_results_lrg_lrg_few <- read_results('./testFolder/500MB_50MB_10files')
read_results_xlg_lrg_mod <- read_results('./testFolder/5000MB_50MB_100files')
print(read_results_sml_mic_mny, digits = 3)
print(read_results_sml_tny_mod, digits = 3)
print(read_results_sml_sml_few, digits = 3)
print(read_results_med_sml_mny, digits = 3)
print(read_results_med_sml_mod, digits = 3)
print(read_results_med_med_few, digits = 3)
print(read_results_lrg_sml_mny, digits = 3)
print(read_results_lrg_med_mod, digits = 3)
print(read_results_lrg_lrg_few, digits = 3)
print(read_results_xlg_lrg_mod, digits = 3)
# display boxplot of my typical use case results & basic machine max load
par(oma = c(0,0,0,0)) # remove overall margins if present
par(mfcol = c(1,1)) # remove grid if present
par(mar = c(12,5,1,1) + 0.1) # to display just a single boxplot with its complete labels
boxplot(read_results_lrg_mid_mid, las = 2, xlab = "", ylab = "Duration (seconds)", main = "40 files @ 12.5MB (500MB)")
boxplot(read_results_xlg_lrg_mod, las = 2, xlab = "", ylab = "Duration (seconds)", main = "100 files @ 50MB (5GB)")
# generate 3x3 grid boxplots
par(oma = c(12,1,1,1)) # margins for the whole 3 x 3 grid plot
par(mfcol = c(3,3)) # create grid (filling down each column)
par(mar = c(1,4,2,1)) # margins for the individual plots in 3 x 3 grid
boxplot(read_results_sml_mic_mny, las = 2, xlab = "", ylab = "Duration (seconds)", main = "1000 files @ 5KB (5MB)", xaxt = 'n')
boxplot(read_results_sml_tny_mod, las = 2, xlab = "", ylab = "Duration (milliseconds)", main = "100 files @ 50KB (5MB)", xaxt = 'n')
boxplot(read_results_sml_sml_few, las = 2, xlab = "", ylab = "Duration (milliseconds)", main = "10 files @ 500KB (5MB)",)
boxplot(read_results_med_sml_mny, las = 2, xlab = "", ylab = "Duration (microseconds) ", main = "1000 files @ 50KB (50MB)", xaxt = 'n')
boxplot(read_results_med_sml_mod, las = 2, xlab = "", ylab = "Duration (microseconds)", main = "100 files @ 500KB (50MB)", xaxt = 'n')
boxplot(read_results_med_med_few, las = 2, xlab = "", ylab = "Duration (seconds)", main = "10 files @ 5MB (50MB)")
boxplot(read_results_lrg_sml_mny, las = 2, xlab = "", ylab = "Duration (seconds)", main = "1000 files @ 500KB (500MB)", xaxt = 'n')
boxplot(read_results_lrg_med_mod, las = 2, xlab = "", ylab = "Duration (seconds)", main = "100 files @ 5MB (500MB)", xaxt = 'n')
boxplot(read_results_lrg_lrg_few, las = 2, xlab = "", ylab = "Duration (seconds)", main = "10 files @ 50MB (500MB)")
मिडिलिंग यूज केस
बड़ा उपयोग मामला
उपयोग मामलों की विविधता
पंक्तियाँ: फ़ाइल गणना (1000, 100, 10)
कॉलम: अंतिम डेटाफ़्रेम आकार (5MB, 50MB, 500MB)
(मूल आकार देखने के लिए चित्र पर क्लिक करें)
आधार आर परिणाम सबसे छोटे उपयोग के मामलों के लिए बेहतर होते हैं जहां बड़े पैमाने पर प्रसंस्करण कार्यों का प्रदर्शन करते समय प्रदर्शन लाभ प्राप्त करने के लिए पूर्र और सी के पुस्तकालयों को लाने के ओवरहेड होते हैं।
यदि आप अपने स्वयं के परीक्षण चलाना चाहते हैं तो आपको यह बैश स्क्रिप्ट मददगार लग सकती है।
for ((i=1; i<=$2; i++)); do
cp "$1" "${1:0:8}_${i}.csv";
done
bash what_you_name_this_script.sh "fileName_you_want_copied" 100
क्रमिक रूप से गिने आपकी फ़ाइल की 100 प्रतियां बनाएगा (फ़ाइल नाम और अंडरस्कोर के प्रारंभिक 8 वर्णों के बाद)।
गुण और प्रशंसा
विशेष धन्यवाद के साथ:
- माइक्रोएन्चमार्क के प्रदर्शन के लिए टायलर रिंकर और अक्रुन।
- मेरे लिए शुरू करने के लिए जेक KAUPP
map_df()
यहाँ ।
- डेविड मैकलॉघलिन ने विज़ुअलाइज़ेशन में सुधार करने और छोटी फ़ाइल, छोटे डेटाफ़्रेम विश्लेषण परिणामों में देखे गए प्रदर्शन व्युत्क्रमों पर चर्चा / पुष्टि करने में सहायक प्रतिक्रिया के लिए।
- के लिए डिफ़ॉल्ट व्यवहार को इंगित करने के लिए marbel
fread()
। (मुझे अध्ययन करने की आवश्यकता है data.table
।)