2014-11-21 72 views
2

我是R新手,我正在練習編寫R函數。我有100個CVS單獨存儲在我的目錄中的 數據文件,並且每個文件都由它的ID標記,例如, 「1」到「100」。 我喜歡寫一個函數,將某些選定的文件讀入R,計算每個數據文件中完整情況的數目 ,並將結果排列到數據框中 下面是函數I首先我讀取「dat」中的所有文件,然後用 rbind函數,將我選擇的文件讀入data.frame中,最後我計算了使用sum(complete.cases())的完整個案數 , )。這看起來簡單,但 功能不起作用。我懷疑有一些錯誤的指數,但 還沒有想通了,爲什麼。通過各種主題的搜查,但找不到有用 答案。非常感謝!R for循環索引問題

`complete = function(directory,id) { 
    dat = list.files(directory, full.name=T) 
    dat.em = data.frame() 
    for (i in id) { 
    dat.ful= rbind(dat.em, read.csv(dat[i])) 
    obs = numeric() 
    obs[i] = sum(complete.cases(dat.ful[dat.ful$ID == i,])) 
    } 
    data.frame(ID = id, count = obs) 
} 
complete("envi",c(1,3,5)) ` 

得到錯誤和警告消息:在data.frame 錯誤(ID = ID,計數= OBS):參數意味着,不同的行數:3,5

回答

3

一個問題與您的代碼是你重置obsnumeric(),因此obs結束時只有一個值(dat中最後一個文件中的完整情況數)。

另一個問題是行dat.ful = rbind(dat.em, read.csv(dat[i]))重置dat.ful以僅包含在該循環的該迭代中正在讀取的數據幀。這不會導致錯誤,但實際上並不需要存儲以前的數據幀,因爲您只是檢查每個讀取的數據幀的完整情況的數量。

下面是使用不同的方法lapply而不是循環。請注意,該函數不是爲函數提供一個索引向量,而是使用一個文件名向量。在你的例子中,你使用索引而不是文件名作爲文件「id」。最好是直接使用文件名,因爲即使文件名是數字,如果出於某種原因,如果文件名向量未按升序數字順序排序,或者如果文件名不要使用連續的數字。

# Read files and return data frame with the number of complete cases in each csv file 
complete = function(directory, files) { 

    # Read each csv file in turn and store its name and number of complete cases 
    # in a list 
    obs.list = lapply(files, function(x) { 
    dat = read.csv(paste0(directory,"/", x)) 
    data.frame(fileName=x, count=sum(complete.cases(dat))) 
    }) 

    # Return a data frame with the number of complete cases for each file 
    return(do.call(rbind, obs.list)) 
} 

然後,要運行該函數,需要給它一個目錄和一個文件名列表。例如,要讀取當前工作目錄中的所有csv文件,可以這樣做:

filesToRead = list.files(pattern=".csv") 

    complete(getwd(), filesToRead)