2014-11-21 120 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)