我是R的新手,我正在练习编写R函数。我有100个cvs分开 存储在我的目录中的数据文件,每个数据文件都用其id标记,例如“1”到“100。 我喜欢编写一个函数,将一些选定的文件读入R,计算出 每个数据文件中的完整案例数,并将结果排列到数据框中。 以下是我写的功能。首先,我读取“dat”中的所有文件。然后,使用 rbind函数,我将我想要的所选文件读入data.frame。最后,我计算了 使用sum(complete.cases())的完整案例数。这似乎很简单但是 该功能不起作用。我怀疑索引有问题但是 还没弄明白为什么。通过各种主题搜索但找不到有用的 回答。非常感谢!
`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,count = obs):参数意味着行数不同:3,5
答案 0 :(得分:3)
您的代码存在的一个问题是,每次循环时都会将obs
重置为numeric()
,因此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)