2014-01-20 30 views
1

我需要編寫一個帶有2個參數的函數:directoryiddirectory本質上是R的直接工作。id是該文件的名稱。所有文件的擴展名爲csv,名稱在001到332之間。如何使用'sapply'或'lapply'來計算n個csv文件中的行數?

函數應該返回一個有兩列的數據幀:idnrowid是該文件的名稱,而nrow是該文件中的行數。

我開始用下面的代碼,但這樣只會用,如果只有1 id得到傳遞給函數的工作:

directory = 'specdata' 
id = 1 # this should be able to take a list of numbers i.e. 1:332 
id1 = if(nchar(id) == 1) {paste("00",id,sep="")} 
     else if (nchar()== 2) {paste("0",id,sep="")}) 
file = paste(directory,"/",as.character(id1),".csv", sep="") 
data = read.csv(file) 
casenum = nrow(data) 
output = c(id1, casenum) 

我如何修改代碼,這樣的功能可以,如果重演超過1 id通過。例如,行id = c(1,2,3,5,6)正在通過? 我正在考慮使用lapplysapply,但不知道從哪裏開始。 謝謝,

+0

也許你可以修改問題的標題來反映問題,也許可以按照'計算指定目錄中每個文件中的行數'的方式進行修改? –

回答

4
  • 如果你只是想在每個文件的行數,然後其實我建議使用下面的命令線工具wc:它會更快。
    wc -l *.csv會給你一個ASCII表格,其中第一列的行數和後面的文件名稱。
    wc的Windows命令行購的,例如作爲GNU core utilities的一部分。)

  • 如果是這樣做的東西目錄中的每個 .csv文件,使用
    file = Sys.glob (paste0 (directory, "/*.csv")

無論如何,這是你要求更具體:

directory = 'specdata' 
id = 1:17 

file = sprintf ("%s/%03i.csv", directory, id) # now a vector with file names 

casenum = sapply (file, function (f) nrow (read.csv (f))) 

cbind (id, casenum) 

# or, if you prefer a data.frame 

data.frame (id = id, casenum = casenum) 
+1

請考慮顯示將與命令行工具'wc'一起使用的代碼。 –

+0

@cbeleites - 謝謝!這就得到了我所需要的,但是對於我自己的學習還有一些問題:a。 「%s /%03i.csv」是什麼意思?b。只能返回2列「id」和「casenum」的結果嗎?現在它也返回文件路徑,因爲第一列是。結果data.frame?或如何使它成爲data.frame?再次感謝!!! – PMa

+0

@PerriMa:'sprintf'語法:'%s'放入一個字符,'%i'輸出一個整數到ASCII 。'%03i'表示整數應該打印至少3位數字,並且應該在開始時填充0到3位數字。參見'?sprintf'會告訴你這個。 – cbeleites

2

儘管沒有必要,但如果您在命名函數中包裝操作,則更容易閱讀。這可以是另一個函數中:

countall <- function(directory, ids) { 
    countlines <- function(id) { 
    ## Your code, copied from the question 
    id1 = if(nchar(id) == 1) {paste("00",id,sep="")} 
     else if (nchar(id)== 2) {paste("0",id,sep="")} 
    file = paste(directory,"/",as.character(id1),".csv", sep="") 
    data = read.csv(file) 
    casenum = nrow(data) 
    ## No need to attach the id here, as you can use the names 
    return(casenum) 
    } 

    retval <- lapply(ids, countlines) # or sapply, to return a vector instead of a list 
    names(retval) <- ids 

    return(retval) 
} 

運行帶:

countall('specdata', 1:10) 
+0

不是id必須是countall的第一個參數嗎?另外,你不需要,例如'lapply(id,countlines,「mydirectory」)' – jlhoward

+1

@jlhoward查看參數順序的簽名。至於第二個問題,'directory'是'countlines'環境中的變量,因此不需要傳遞給lapply。 –

+0

@MatthewLundberg - 一對夫婦的編輯(我不知道如何讓它到你原來的帖子):a)。在'else if(nchar()..'b)中缺少'id'。在同一行的末尾有一個額外的''''。另外,我用'countall('specdata',1:10)運行你的代碼,並得到錯誤信息'無法打開文件'specdata/.csv':沒有這樣的文件或目錄。看起來id在'specdata /'之後沒有被粘貼? – PMa

相關問題