[英]How can I determine the longest common substring in two columns of a LARGE data.table in R
[英]How can I cut large csv files using any R packages like ff or data.table?
我想剪切大型csv文件(文件大小超過RAM大小)並使用它們或將每個文件保存在磁盤中供以后使用。 對於大文件,哪個R包最適合這樣做?
我沒有嘗試過但在read.table
或read.csv
使用skip
和nrows
參數值得一試。 這些來自?read.table
skip integer:開始讀取數據之前要跳過的數據文件的行數。
nrows integer:要讀入的最大行數。將忽略負值和其他無效值。
為了避免一些麻煩的問題,你需要做一些錯誤處理。 換句話說,當跳過值大於你的大csv中的行數時,我不知道什么是開心的。
ps我也不知道header=TRUE
是否影響skip,你還必須檢查。
給@berkorbay的答案是可以的,我可以確認標題可以與skip一起使用。 但是,如果您的文件非常大,則會變得非常緩慢,因為在第一個之后的每個后續讀取必須跳過所有先前讀取的行。
我不得不做類似的事情,在浪費了相當多的時間之后,我在PERL中編寫了一個簡短的腳本,它將原始文件分成塊,你可以一個接一個地閱讀。 它要快得多。 我在這里附上了源代碼,翻譯了一些部分,以便明確意圖:
#!/usr/bin/perl
system("cls");
print("Fragment .csv file keeping header in each chunk\n") ;
print("\nEnter input file name = ") ;
$entrada = <STDIN> ;
print("\nEnter maximum number of lines in each fragment = ") ;
$nlineas = <STDIN> ;
print("\nEnter output file name stem = ") ;
$salida = <STDIN> ;
chop($salida) ;
open(IN,$entrada) || die "Cannot open input file: $!\n" ;
$cabecera = <IN> ;
$leidas = 0 ;
$fragmento = 1 ;
$fichero = $salida.$fragmento ;
open(OUT,">$fichero") || die "Cannot open output file: $!\n" ;
print OUT $cabecera ;
while(<IN>) {
if ($leidas > $nlineas) {
close(OUT) ;
$fragmento++ ;
$fichero = $salida.$fragmento ;
open(OUT,">$fichero") || die "Cannot open output file: $!\n" ;
print OUT $cabecera ;
$leidas = 0;
}
$leidas++ ;
print OUT $_ ;
}
close(OUT) ;
只需保存任何名稱並執行即可。 如果你在不同的地方有PERL,可能必須改變第一行(如果你在Windows上,你必須調用腳本作為“perl name-of-script”)。
應該使用ff包的read.csv.ffdf和這樣的特定參數來讀取大文件:
library(ff)
a <- read.csv.ffdf(file="big.csv", header=TRUE, VERBOSE=TRUE, first.rows=1000000, next.rows=1000000, colClasses=NA)
將大文件讀入ff對象后,可以使用以下命令將ffobject子設置為數據幀:a [1000:1000000,]
和保存用於子集的代碼的其余部分破dataframes totalrows =暗淡的(a)[1] row.size = as.integer(object.size(A [1:10000,]))/ 10000 #IN字節
block.size = 200000000 #in bytes .IN Mbs 200 Mb
#rows.block is rows per block
rows.block = ceiling(block.size/row.size)
#nmaps is the number of chunks/maps of big dataframe(ff), nmaps = number of maps - 1
nmaps = floor(totalrows/rows.block)
for(i in (0:nmaps)){
if(i==nmaps){
df = a[(i*rows.block+1) : totalrows,]
}
else{
df = a[(i*rows.block+1) : ((i+1)*rows.block),]
}
#process df or save it
write.csv(df,paste0("M",i+1,".csv"))
#remove df
rm(df)
}
或者,您可以先使用dbWriteTable將文件讀入mysql,然后使用ETLUtils包中的read.dbi.ffdf函數將其讀回R.考慮下面的函數;
read.csv.sql.ffdf <- function(file, name,overwrite = TRUE, header = TRUE, drv = MySQL(), dbname = "new", username = "root",host='localhost', password = "1234"){ conn = dbConnect(drv, user = username, password = password, host = host, dbname = dbname) dbWriteTable(conn, name, file, header = header, overwrite = overwrite) on.exit(dbRemoveTable(conn, name)) command = paste0("select * from ", name) ret = read.dbi.ffdf(command, dbConnect.args = list(drv =drv, dbname = dbname, username = username, password = password)) return(ret) }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.